diff --git a/Cargo.lock b/Cargo.lock index 6e3e2fced..e1af99433 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -71,7 +71,7 @@ checksum = "1a047897373be4bbb0224c1afdabca92648dc57a9c9ef6e7b0be3aff7a859c83" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.50", ] [[package]] @@ -87,7 +87,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.50", "syn-solidity", "tiny-keccak", ] @@ -105,9 +105,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.79" +version = "1.0.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" +checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1" [[package]] name = "async-trait" @@ -117,7 +117,7 @@ checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.50", ] [[package]] @@ -164,9 +164,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.85" +version = "1.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b918671670962b48bc23753aef0c51d072dca6f52f01f800854ada6ddb7f7d3" +checksum = "3286b845d0fccbdd15af433f61c5970e711987036cb468f437ff6badd70f4e24" [[package]] name = "cfg-if" @@ -273,9 +273,9 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" -version = "0.3.5" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0c62115964e08cb8039170eb33c1d0e2388a256930279edca206fff675f82c3" +checksum = "379dada1584ad501b383485dd706b8afb7a70fcbc7f4da7d780638a5a6124a60" [[package]] name = "hex" @@ -328,6 +328,7 @@ dependencies = [ "async-trait", "hashbrown", "serde", + "unsigned-varint", ] [[package]] @@ -657,7 +658,7 @@ checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.50", ] [[package]] @@ -677,12 +678,12 @@ checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" [[package]] name = "socket2" -version = "0.5.5" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" dependencies = [ "libc", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -707,9 +708,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.48" +version = "2.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "74f1bdc9872430ce9b75da68329d1c1746faf50ffac5f19e02b71e37ff881ffb" dependencies = [ "proc-macro2", "quote", @@ -725,7 +726,7 @@ dependencies = [ "paste", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.50", ] [[package]] @@ -776,7 +777,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.50", ] [[package]] @@ -791,6 +792,12 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +[[package]] +name = "unsigned-varint" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb066959b24b5196ae73cb057f45598450d2c5f71460e98c49b738086eff9c06" + [[package]] name = "valuable" version = "0.1.0" @@ -824,7 +831,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.52.3", ] [[package]] @@ -844,17 +851,17 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.0" +version = "0.52.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +checksum = "d380ba1dc7187569a8a9e91ed34b8ccfc33123bbacb8c0aed2d1ad7f3ef2dc5f" dependencies = [ - "windows_aarch64_gnullvm 0.52.0", - "windows_aarch64_msvc 0.52.0", - "windows_i686_gnu 0.52.0", - "windows_i686_msvc 0.52.0", - "windows_x86_64_gnu 0.52.0", - "windows_x86_64_gnullvm 0.52.0", - "windows_x86_64_msvc 0.52.0", + "windows_aarch64_gnullvm 0.52.3", + "windows_aarch64_msvc 0.52.3", + "windows_i686_gnu 0.52.3", + "windows_i686_msvc 0.52.3", + "windows_x86_64_gnu 0.52.3", + "windows_x86_64_gnullvm 0.52.3", + "windows_x86_64_msvc 0.52.3", ] [[package]] @@ -865,9 +872,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.0" +version = "0.52.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" +checksum = "68e5dcfb9413f53afd9c8f86e56a7b4d86d9a2fa26090ea2dc9e40fba56c6ec6" [[package]] name = "windows_aarch64_msvc" @@ -877,9 +884,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.0" +version = "0.52.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" +checksum = "8dab469ebbc45798319e69eebf92308e541ce46760b49b18c6b3fe5e8965b30f" [[package]] name = "windows_i686_gnu" @@ -889,9 +896,9 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.0" +version = "0.52.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" +checksum = "2a4e9b6a7cac734a8b4138a4e1044eac3404d8326b6c0f939276560687a033fb" [[package]] name = "windows_i686_msvc" @@ -901,9 +908,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.0" +version = "0.52.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" +checksum = "28b0ec9c422ca95ff34a78755cfa6ad4a51371da2a5ace67500cf7ca5f232c58" [[package]] name = "windows_x86_64_gnu" @@ -913,9 +920,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.0" +version = "0.52.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" +checksum = "704131571ba93e89d7cd43482277d6632589b18ecf4468f591fbae0a8b101614" [[package]] name = "windows_x86_64_gnullvm" @@ -925,9 +932,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.0" +version = "0.52.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" +checksum = "42079295511643151e98d61c38c0acc444e52dd42ab456f7ccfd5152e8ecf21c" [[package]] name = "windows_x86_64_msvc" @@ -937,9 +944,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.0" +version = "0.52.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +checksum = "0770833d60a970638e989b3fa9fd2bb1aaadcf88963d1659fd7d9990196ed2d6" [[package]] name = "zerocopy" @@ -958,7 +965,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.50", ] [[package]] diff --git a/crates/derive/Cargo.toml b/crates/derive/Cargo.toml index 3bb3abf75..9f26eaf77 100644 --- a/crates/derive/Cargo.toml +++ b/crates/derive/Cargo.toml @@ -18,6 +18,7 @@ alloy-rlp = { version = "0.3.4", default-features = false, features = ["derive"] alloy-sol-types = { version = "0.6.3", default-features = false } async-trait = "0.1.77" hashbrown = "0.14.3" +unsigned-varint = "0.8.0" # Optional serde = { version = "1.0.197", default-features = false, features = ["derive"], optional = true } diff --git a/crates/derive/src/types/mod.rs b/crates/derive/src/types/mod.rs index 3632c9df9..da8a53720 100644 --- a/crates/derive/src/types/mod.rs +++ b/crates/derive/src/types/mod.rs @@ -1,5 +1,8 @@ //! This module contains all of the types used within the derivation pipeline. +use alloc::vec::Vec; +use alloy_rlp::{Decodable, Encodable}; + mod system_config; pub use system_config::{SystemAccounts, SystemConfig, SystemConfigUpdateType}; @@ -38,3 +41,35 @@ pub use channel::Channel; mod errors; pub use errors::{StageError, StageResult}; + +mod single_batch; +pub use single_batch::SingleBatch; + +/// A raw transaction +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct RawTransaction(pub Vec); + +impl Encodable for RawTransaction { + fn encode(&self, out: &mut dyn alloy_rlp::BufMut) { + self.0.encode(out) + } +} + +impl Decodable for RawTransaction { + /// Decodes RLP encoded bytes into [RawTransaction] bytes + fn decode(buf: &mut &[u8]) -> alloy_rlp::Result { + let tx_bytes: Vec = Decodable::decode(buf)?; + Ok(Self(tx_bytes)) + } +} + +/// A single L2 block derived from a batch. +#[derive(Debug, Clone)] +pub struct BlockInput { + /// Timestamp of the L2 block + pub timestamp: u64, + /// Transactions included in this block + pub transactions: Vec, + /// The L1 block this batch was fully derived from + pub l1_inclusion_block: u64, +} diff --git a/crates/derive/src/types/single_batch.rs b/crates/derive/src/types/single_batch.rs new file mode 100644 index 000000000..9122efa7f --- /dev/null +++ b/crates/derive/src/types/single_batch.rs @@ -0,0 +1,97 @@ +//! This module contains the [SingleBatch] type. + +use super::RawTransaction; +use alloc::vec::Vec; +use alloy_primitives::BlockHash; +use alloy_rlp::{Decodable, Encodable}; + +/// Represents a single batch: a single encoded L2 block +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct SingleBatch { + /// Block hash of the previous L2 block + pub parent_hash: BlockHash, + /// The batch epoch number. Same as the first L1 block number in the epoch. + pub epoch_num: u64, + /// The block hash of the first L1 block in the epoch + pub epoch_hash: BlockHash, + /// The L2 block timestamp of this batch + pub timestamp: u64, + /// The L2 block transactions in this batch + pub transactions: Vec, +} + +impl Encodable for SingleBatch { + fn encode(&self, out: &mut dyn alloy_rlp::BufMut) { + self.parent_hash.encode(out); + self.epoch_num.encode(out); + self.epoch_hash.encode(out); + self.timestamp.encode(out); + self.transactions.encode(out); + } +} + +impl Decodable for SingleBatch { + fn decode(buf: &mut &[u8]) -> alloy_rlp::Result { + let parent_hash = Decodable::decode(buf)?; + let epoch_num = Decodable::decode(buf)?; + let epoch_hash = Decodable::decode(buf)?; + let timestamp = Decodable::decode(buf)?; + let transactions = Decodable::decode(buf)?; + + Ok(SingleBatch { + parent_hash, + epoch_num, + epoch_hash, + timestamp, + transactions, + }) + } +} + +impl SingleBatch { + /// If any transactions are empty or deposited transaction types. + pub fn has_invalid_transactions(&self) -> bool { + self.transactions + .iter() + .any(|tx| tx.0.is_empty() || tx.0[0] == 0x7E) + } +} + +#[cfg(test)] +mod test { + use super::SingleBatch; + use crate::types::RawTransaction; + use alloc::vec; + use alloy_primitives::B256; + use alloy_rlp::{BytesMut, Decodable, Encodable}; + + #[test] + fn test_single_batch_rlp_roundtrip() { + let single_batch = SingleBatch { + parent_hash: B256::ZERO, + epoch_num: 0xFF, + epoch_hash: B256::ZERO, + timestamp: 0xEE, + transactions: vec![RawTransaction(vec![0x00])], + }; + + let mut out_buf = BytesMut::default(); + single_batch.encode(&mut out_buf); + let decoded = SingleBatch::decode(&mut out_buf.as_ref()).unwrap(); + assert_eq!(decoded, single_batch); + assert!(!single_batch.has_invalid_transactions()); + } + + #[test] + fn test_single_batch_invalid_transactions() { + let single_batch = SingleBatch { + parent_hash: B256::ZERO, + epoch_num: 0xFF, + epoch_hash: B256::ZERO, + timestamp: 0xEE, + transactions: vec![RawTransaction(vec![0x7E])], + }; + + assert!(single_batch.has_invalid_transactions()); + } +}