-
Notifications
You must be signed in to change notification settings - Fork 6
feat: derivation pipeline #40
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
Merged
Merged
Changes from 17 commits
Commits
Show all changes
24 commits
Select commit
Hold shift + click to select a range
a04f6b7
test: move calldata to files
greged93 4c328cc
feat: batch header decoding
greged93 53af94f
feat: improve codec interface
greged93 c17d65e
chore: manifests fixes
greged93 a2929e0
feat: revert some codec changes
greged93 05cc350
feat: wip derivation pipeline
greged93 54a557c
feat: batch header v7
greged93 a5e31c9
feat: add batch abstraction
greged93 57c0992
feat: basic derivation pipeline
greged93 2edae45
feat: implement batch data hash
greged93 113f18e
feat: move PayloadData
greged93 9186662
feat: improve batch data hash computation
greged93 42bbace
test: derivation
greged93 50962ca
chore: cleaning
greged93 2aa6b85
fix: lints
greged93 32e56fc
fix: lints
greged93 2f56e24
fix: skip wasm for derivation pipeline
greged93 fb85ecf
fix: data hash computation for batch
greged93 6341957
Merge branch 'main' into feat/derivation-pipeline
greged93 23be55b
fix: lint
greged93 df9d787
fix: lint
greged93 4bba46d
fix: lints
greged93 485f66c
fix: answer comments
greged93 b1b223e
fix: lints
greged93 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,118 @@ | ||
| use crate::{BlockContext, L2Block, decoding::payload::PayloadData}; | ||
| use alloy_primitives::{B256, bytes::BufMut, keccak256}; | ||
| use scroll_alloy_consensus::TxL1Message; | ||
|
|
||
| /// The deserialized batch data. | ||
| #[derive(Debug, Clone, PartialEq, Eq)] | ||
| pub struct Batch { | ||
| /// The batch version. | ||
| pub version: u8, | ||
| /// The amount of blocks for each chunk of the batch. Only relevant for codec versions v0 -> | ||
| /// v6. | ||
| pub chunks_block_count: Option<Vec<usize>>, | ||
| /// The data for the batch. | ||
| pub data: PayloadData, | ||
| } | ||
|
|
||
| impl Batch { | ||
| /// Returns a new instance of a batch. | ||
| pub fn new(version: u8, chunks_block_count: Option<Vec<usize>>, data: PayloadData) -> Self { | ||
| Self { version, chunks_block_count, data } | ||
| } | ||
|
|
||
| /// Computes the hash for the batch, using the provided L1 messages associated with each block. | ||
| pub fn try_hash(&self, l1_messages: &[TxL1Message]) -> Option<B256> { | ||
| // From version 7 and above, the batch doesn't have a data hash. | ||
| if self.version >= 7 { | ||
| return None; | ||
| } | ||
|
|
||
| let chunks_count = self.chunks_block_count.as_ref()?; | ||
| let blocks_buf = &mut (&**self.data.l2_blocks()); | ||
| let l1_messages = &mut (&*l1_messages); | ||
|
|
||
| let mut chunk_hashes = Vec::with_capacity(chunks_count.len() * 32); | ||
frisitano marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| for chunk_count in chunks_count { | ||
| // slice the blocks at chunk_count and filter l1 message. | ||
| let blocks = blocks_buf.get(..*chunk_count)?; | ||
| let l1_messages_count = blocks.iter().map(|b| b.context.num_l1_messages as usize).sum(); | ||
| let messages = l1_messages.get(..l1_messages_count)?; | ||
frisitano marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| // compute the chunk data hash. | ||
| chunk_hashes.append(&mut hash_chunk(self.version, blocks, messages).to_vec()); | ||
|
|
||
| // advance the buffer. | ||
| *blocks_buf = blocks_buf.get(*chunk_count..).unwrap_or(&[]); | ||
| } | ||
|
|
||
| Some(keccak256(chunk_hashes)) | ||
| } | ||
| } | ||
|
|
||
| /// Compute the hash for the chunk. | ||
| fn hash_chunk(version: u8, l2_blocks: &[L2Block], l1_messages: &[TxL1Message]) -> B256 { | ||
| // reserve the correct capacity. | ||
| let mut capacity = l2_blocks.len() * (BlockContext::BYTES_LENGTH - 2) + l1_messages.len() * 32; | ||
| if version == 0 { | ||
| capacity += l2_blocks.iter().map(|b| b.transactions.len()).sum::<usize>(); | ||
| } | ||
| let mut buf = Vec::with_capacity(capacity); | ||
|
|
||
| for block in l2_blocks { | ||
| let context = block.context.to_be_bytes(); | ||
| // we don't use the last 2 bytes. | ||
| // <https://github.com/scroll-tech/da-codec/blob/main/encoding/codecv0_types.go#L175> | ||
| buf.put_slice(&context[..BlockContext::BYTES_LENGTH - 2]); | ||
| } | ||
|
|
||
| for l1_message in l1_messages { | ||
| buf.put_slice(l1_message.tx_hash().as_slice()) | ||
| } | ||
|
|
||
| // for v0, we add the l2 transaction hashes. | ||
| if version == 0 { | ||
| for block in l2_blocks { | ||
| for tx in &block.transactions { | ||
| buf.put_slice(keccak256(&tx.0).as_slice()); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| keccak256(buf) | ||
| } | ||
|
|
||
| #[cfg(test)] | ||
| mod tests { | ||
| use crate::decoding::{test_utils::read_to_bytes, v0::decode_v0}; | ||
|
|
||
| use crate::decoding::v1::decode_v1; | ||
| use alloy_primitives::b256; | ||
|
|
||
| #[test] | ||
| fn test_should_compute_data_hash_v0() -> eyre::Result<()> { | ||
| // <https://etherscan.io/tx/0x2c7bb77d6086befd9bdcf936479fd246d1065cbd2c6aff55b1d39a67aff965c1> | ||
| let raw_calldata = read_to_bytes("../codec/testdata/calldata_v0.bin")?; | ||
| let batch = decode_v0(&raw_calldata)?; | ||
|
|
||
| let hash = batch.try_hash(&[]).unwrap(); | ||
|
|
||
| assert_eq!(hash, b256!("33e608dbf683c1ee03a34d01de52f67d60a0563b7e713b65a7395bb3b646f71f")); | ||
|
|
||
| Ok(()) | ||
| } | ||
|
|
||
| #[test] | ||
| fn test_should_compute_data_hash_v1() -> eyre::Result<()> { | ||
| // <https://etherscan.io/tx/0x27d73eef6f0de411f8db966f0def9f28c312a0ae5cfb1ac09ec23f8fa18b005b> | ||
| let raw_calldata = read_to_bytes("../codec/testdata/calldata_v1.bin")?; | ||
| let blob = read_to_bytes("../codec/testdata/blob_v1.bin")?; | ||
| let batch = decode_v1(&raw_calldata, &blob)?; | ||
|
|
||
| let hash = batch.try_hash(&[]).unwrap(); | ||
|
|
||
| assert_eq!(hash, b256!("c20f5914a772663080f8a77955b33814a04f7a19c880536e562a1bcfd5343a37")); | ||
|
|
||
| Ok(()) | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| //! Commit payload. | ||
| use crate::L2Block; | ||
| use alloy_primitives::B256; | ||
| use std::vec::Vec; | ||
|
|
||
| /// The payload data on the L1. | ||
| #[derive(Debug, Clone, PartialEq, Eq)] | ||
| pub struct PayloadData { | ||
| /// The L2 blocks from the commit payload. | ||
| pub blocks: Vec<L2Block>, | ||
| /// Contains information about the current state of the L1 message queue. | ||
| pub l1_message_queue_info: L1MessageQueueInfo, | ||
| } | ||
|
|
||
| /// Information about the state of the L1 message queue. | ||
| #[derive(Debug, Clone, PartialEq, Eq, derive_more::From)] | ||
| pub enum L1MessageQueueInfo { | ||
| /// The queue index of the l1 message. | ||
| Indexed(u64), | ||
frisitano marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| /// The hashed state of the l1 message queue. | ||
| Hashed { | ||
| /// The previous l1 message queue hash. | ||
| prev_l1_message_queue_hash: B256, | ||
| /// The post l1 message queue hash. | ||
| post_l1_message_queue_hash: B256, | ||
| }, | ||
| } | ||
|
|
||
| impl PayloadData { | ||
| /// Returns the list [`L2Block`] committed. | ||
| pub fn l2_blocks(&self) -> &Vec<L2Block> { | ||
| &self.blocks | ||
| } | ||
|
|
||
| /// Returns the list [`L2Block`] committed. | ||
| pub fn into_l2_blocks(self) -> Vec<L2Block> { | ||
| self.blocks | ||
| } | ||
|
|
||
| /// Returns the l1 message queue index of the first message in the batch. | ||
| pub fn queue_index_start(&self) -> Option<u64> { | ||
| match self.l1_message_queue_info { | ||
| L1MessageQueueInfo::Indexed(index) => Some(index), | ||
| L1MessageQueueInfo::Hashed { .. } => None, | ||
| } | ||
| } | ||
|
|
||
| /// Returns the l1 message queue hash before the commitment of the batch. | ||
| pub fn prev_l1_message_queue_hash(&self) -> Option<&B256> { | ||
| match self.l1_message_queue_info { | ||
| L1MessageQueueInfo::Indexed(_) => None, | ||
| L1MessageQueueInfo::Hashed { ref prev_l1_message_queue_hash, .. } => { | ||
| Some(prev_l1_message_queue_hash) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /// Returns the l1 message queue hash after the commitment of the batch. | ||
| pub fn post_l1_message_queue_hash(&self) -> Option<&B256> { | ||
| match self.l1_message_queue_info { | ||
| L1MessageQueueInfo::Indexed(_) => None, | ||
| L1MessageQueueInfo::Hashed { ref post_l1_message_queue_hash, .. } => { | ||
| Some(post_l1_message_queue_hash) | ||
| } | ||
| } | ||
| } | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.