Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(book): Batch over SingleBatch #260

Merged
merged 5 commits into from
Nov 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions book/src/examples/batch-to-frames.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
>
> Steps and handling of types with respect to chain tip, ordering of frames, re-orgs, and
> more are not covered by this example. This example solely demonstrates the most trivial
> way to transform an individual [`SingleBatch`][batch] into [`Frame`][frame]s.
> way to transform an individual [`Batch`][batch] into [`Frame`][frame]s.

This example walks through transforming a [`SingleBatch`][single-batch] into [`Frame`][frame]s.
This example walks through transforming a [`Batch`][batch] into [`Frame`][frame]s.

Effectively, this example demonstrates the _encoding_ process from an L2 batch into the
serialized bytes that are posted to the data availability layer.
Expand All @@ -20,19 +20,19 @@ serialized bytes that are posted to the data availability layer.
The high level transformation is the following.

```
SingleBatch -> decompressed batch data -> ChannelOut -> frames[] -> bytes[]
Batch -> decompressed batch data -> ChannelOut -> frames[] -> bytes[]
```

Given the [`SingleBatch`][single-batch], the first step to encode the batch
using the [`SingleBatch::encode()`][encode-batch] method. The output bytes
Given the [`Batch`][batch], the first step to encode the batch
using the [`Batch::encode()`][encode-batch] method. The output bytes
need to then be compressed prior to adding them to the
[`ChannelOut`][channel-out].

> [!NOTE]
>
> The [`ChannelOut`][channel-out] type also provides a method for adding
> the [`SingleBatch`][single-batch] itself, handling encoding and
> compression, but this method is not available yet.
> the [`Batch`][batch] itself, handling encoding and compression, but
> this method is not available yet.

Once compressed using the helper `compress_brotli` method, the compressed
bytes can be added to a newly constructed [`ChannelOut`][channel-out].
Expand Down
11 changes: 5 additions & 6 deletions book/src/examples/frames-to-batch.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,16 @@
>
> Steps and handling of types with respect to chain tip, ordering of frames, re-orgs, and
> more are not covered by this example. This example solely demonstrates the most trivial
> way to transform individual [`Frame`][frame]s into a [`SingleBatch`][batch] type.
> way to transform individual [`Frame`][frame]s into a [`Batch`][batch] type.

This example walks through transforming [`Frame`][frame]s into the [`SingleBatch`][single-batch]
types.
This example walks through transforming [`Frame`][frame]s into the [`Batch`][batch] types.

## Walkthrough

The high level transformation is the following.

```
raw bytes[] -> frames[] -> channel -> decompressed channel data -> SingleBatch
raw bytes[] -> frames[] -> channel -> decompressed channel data -> Batch
```

Given the raw, batch-submitted frame data as bytes (read in with the [`hex!` macro][hex]),
Expand All @@ -38,8 +37,8 @@ the frame data can taken from the [`Channel`][channel] using
and needs to be decompressed using the respective compression algorithm depending on
which hardforks are activated (using the `RollupConfig`). For the sake of this example,
`brotli` is used (which was activated in the [Fjord hardfork][fjord]). Decompressed
brotli bytes can then be passed right into [`SingleBatch::decode`][decode-batch]
to wind up with the example's desired [`SingleBatch`][single-batch].
brotli bytes can then be passed right into [`Batch::decode`][decode-batch]
to wind up with the example's desired [`Batch`][batch].


> [!Note]
Expand Down
14 changes: 7 additions & 7 deletions crates/protocol/examples/batch_to_frames.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,10 @@
use alloy_consensus::{SignableTransaction, TxEip1559};
use alloy_eips::eip2718::{Decodable2718, Encodable2718};
use alloy_primitives::{hex, Address, BlockHash, Bytes, PrimitiveSignature, U256};
use alloy_rlp::{Decodable, Encodable};
use brotli::enc::{BrotliCompress, BrotliEncoderParams};
use op_alloy_consensus::OpTxEnvelope;
use op_alloy_genesis::RollupConfig;
use op_alloy_protocol::{ChannelId, ChannelOut, SingleBatch, CHANNEL_ID_LENGTH};
use op_alloy_protocol::{Batch, ChannelId, ChannelOut, SingleBatch, CHANNEL_ID_LENGTH};

fn main() {
// Use the example transaction
Expand All @@ -32,23 +31,24 @@ fn main() {
let timestamp = 1;

let single_batch = SingleBatch { parent_hash, epoch_num, epoch_hash, timestamp, transactions };
let batch = Batch::Single(single_batch);

// Encode the batch.
let mut encoded = Vec::new();
single_batch.encode(&mut encoded);
let decoded = SingleBatch::decode(&mut encoded.as_slice()).unwrap();
assert_eq!(single_batch, decoded);
batch.encode(&mut encoded).unwrap();
let config = RollupConfig::default();
let decoded = Batch::decode(&mut encoded.as_slice(), &config).unwrap();
assert_eq!(batch, decoded);
println!("Encoded Batch: {}", hex::encode(&encoded));

// Compress the encoded batch.
let compressed = compress_brotli(&encoded);
let expected = hex!("1b1201f82f0f6c3734f4821cd090ef3979d71a98e7e483b1dccdd525024c0ef16f425c7b4976a7acc0c94a0514b72c096d4dcc52f0b22dae193c70c86d0790a304a08152c8250031d011fe80c23600004009b67bf33d17f4b6831018ad78018613b3403bc2fc6da91e8fc8a29031b3417774a33bf1f30534ea695b09eb3bf26cb553530e9fa2120e755ec5bd3a2bc75b2ee300");
let expected = hex!("1b1301f82f0f6c3734f4821cd090ef3979d71a98e7e483b1dccdd525024c0ef16f425c7b4976a7acc0c94a0514b72c096d4dcc52f0b22dae193c70c86d0790a304a08152c8250031d091063ea0b00d00005082edde7ccf05bded2004462b5e80e1c42cd08e307f5baac723b22864cc6cd01ddde84efc7c018d7ada56c2fa8e3c5bedd494c3a7a884439d5771afcecaf196cb38");
assert_eq!(compressed, expected);
println!("Brotli-compressed batch: {}", hex::encode(&compressed));

// Create a new channel.
let id = random_channel_id();
let config = RollupConfig::default();
let mut channel_out = ChannelOut::new(id, &config);

// Add the compressed batch to the `ChannelOut`.
Expand Down
17 changes: 9 additions & 8 deletions crates/protocol/examples/frames_to_batch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
use alloy_consensus::{SignableTransaction, TxEip1559};
use alloy_eips::eip2718::{Decodable2718, Encodable2718};
use alloy_primitives::{hex, Address, BlockHash, Bytes, PrimitiveSignature, U256};
use alloy_rlp::Decodable;
use op_alloy_consensus::OpTxEnvelope;
use op_alloy_protocol::{BlockInfo, Channel, Frame, SingleBatch};
use op_alloy_genesis::RollupConfig;
use op_alloy_protocol::{Batch, BlockInfo, Channel, Frame, SingleBatch};
use std::io::Read;

fn main() {
// Raw frame data taken from the `encode_channel` example.
let first_frame = hex!("d9529e42ee95431e983d7e96dc2f2f0400000000004d1b1201f82f0f6c3734f4821cd090ef3979d71a98e7e483b1dccdd525024c0ef16f425c7b4976a7acc0c94a0514b72c096d4dcc52f0b22dae193c70c86d0790a304a08152c8250031d011fe80c200");
let second_frame = hex!("d9529e42ee95431e983d7e96dc2f2f040001000000463600004009b67bf33d17f4b6831018ad78018613b3403bc2fc6da91e8fc8a29031b3417774a33bf1f30534ea695b09eb3bf26cb553530e9fa2120e755ec5bd3a2bc75b2ee30001");
let first_frame = hex!("60d54f49b71978b1b09288af847b11d200000000004d1b1301f82f0f6c3734f4821cd090ef3979d71a98e7e483b1dccdd525024c0ef16f425c7b4976a7acc0c94a0514b72c096d4dcc52f0b22dae193c70c86d0790a304a08152c8250031d091063ea000");
let second_frame = hex!("60d54f49b71978b1b09288af847b11d2000100000046b00d00005082edde7ccf05bded2004462b5e80e1c42cd08e307f5baac723b22864cc6cd01ddde84efc7c018d7ada56c2fa8e3c5bedd494c3a7a884439d5771afcecaf196cb3801");

// Decode the raw frames.
let decoded_first = Frame::decode(&first_frame).expect("decodes frame").1;
Expand All @@ -36,19 +36,20 @@ fn main() {
println!("Decompressed frame data: {}", hex::encode(&decompressed));

// Decode the single batch from the decompressed data.
let batch = SingleBatch::decode(&mut decompressed.as_slice()).expect("batch decodes");
let config = RollupConfig::default();
let batch = Batch::decode(&mut decompressed.as_slice(), &config).expect("batch decodes");
assert_eq!(
batch,
SingleBatch {
Batch::Single(SingleBatch {
parent_hash: BlockHash::ZERO,
epoch_num: 1,
epoch_hash: BlockHash::ZERO,
timestamp: 1,
transactions: example_transactions(),
}
})
);

println!("Successfully decoded frames into a SingleBatch");
println!("Successfully decoded frames into a Batch");
}

/// Decompresses the given bytes data using the Brotli decompressor implemented
Expand Down
Loading