From afb636c992308f6a3f47f22139f8b7979774856f Mon Sep 17 00:00:00 2001 From: refcell Date: Fri, 25 Oct 2024 15:55:12 -0400 Subject: [PATCH 1/3] feat: batch type --- crates/protocol/src/batch_type.rs | 77 +++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 crates/protocol/src/batch_type.rs diff --git a/crates/protocol/src/batch_type.rs b/crates/protocol/src/batch_type.rs new file mode 100644 index 000000000..df4169924 --- /dev/null +++ b/crates/protocol/src/batch_type.rs @@ -0,0 +1,77 @@ +//! Batch Types +//! +//! This module contains the batch types for the OP Stack derivation pipeline. +//! +//! ## Batch +//! +//! A batch is either a `SpanBatch` or a `SingleBatch`. +//! +//! The batch type is encoded as a single byte: +//! - `0x00` for a `SingleBatch` +//! - `0x01` for a `SpanBatch` + +use alloy_rlp::{Decodable, Encodable}; + +/// The single batch type identifier. +pub const SINGLE_BATCH_TYPE: u8 = 0x00; + +/// The span batch type identifier. +pub const SPAN_BATCH_TYPE: u8 = 0x01; + +/// The Batch Type. +#[derive(Debug, Clone, PartialEq, Eq)] +#[repr(u8)] +pub enum BatchType { + /// Single Batch. + Single = SINGLE_BATCH_TYPE, + /// Span Batch. + Span = SPAN_BATCH_TYPE, +} + +impl From for BatchType { + fn from(val: u8) -> Self { + match val { + SINGLE_BATCH_TYPE => Self::Single, + SPAN_BATCH_TYPE => Self::Span, + _ => panic!("Invalid batch type: {val}"), + } + } +} + +impl From<&[u8]> for BatchType { + fn from(buf: &[u8]) -> Self { + Self::from(buf[0]) + } +} + +impl Encodable for BatchType { + fn encode(&self, out: &mut dyn alloy_rlp::BufMut) { + let val = match self { + Self::Single => SINGLE_BATCH_TYPE, + Self::Span => SPAN_BATCH_TYPE, + }; + val.encode(out); + } +} + +impl Decodable for BatchType { + fn decode(buf: &mut &[u8]) -> alloy_rlp::Result { + let val = u8::decode(buf)?; + Ok(Self::from(val)) + } +} + +#[cfg(test)] +mod test { + use super::*; + use alloc::vec::Vec; + + #[test] + fn test_batch_type_rlp_roundtrip() { + let batch_type = BatchType::Single; + let mut buf = Vec::new(); + batch_type.encode(&mut buf); + let decoded = BatchType::decode(&mut buf.as_slice()).unwrap(); + assert_eq!(batch_type, decoded); + } +} From 83d6a2ed773d6afb769d5959a16d5c5eef715f36 Mon Sep 17 00:00:00 2001 From: refcell Date: Fri, 25 Oct 2024 16:10:56 -0400 Subject: [PATCH 2/3] fix: move into a subdir --- crates/protocol/src/batch_type.rs | 77 ------------------------------- 1 file changed, 77 deletions(-) delete mode 100644 crates/protocol/src/batch_type.rs diff --git a/crates/protocol/src/batch_type.rs b/crates/protocol/src/batch_type.rs deleted file mode 100644 index df4169924..000000000 --- a/crates/protocol/src/batch_type.rs +++ /dev/null @@ -1,77 +0,0 @@ -//! Batch Types -//! -//! This module contains the batch types for the OP Stack derivation pipeline. -//! -//! ## Batch -//! -//! A batch is either a `SpanBatch` or a `SingleBatch`. -//! -//! The batch type is encoded as a single byte: -//! - `0x00` for a `SingleBatch` -//! - `0x01` for a `SpanBatch` - -use alloy_rlp::{Decodable, Encodable}; - -/// The single batch type identifier. -pub const SINGLE_BATCH_TYPE: u8 = 0x00; - -/// The span batch type identifier. -pub const SPAN_BATCH_TYPE: u8 = 0x01; - -/// The Batch Type. -#[derive(Debug, Clone, PartialEq, Eq)] -#[repr(u8)] -pub enum BatchType { - /// Single Batch. - Single = SINGLE_BATCH_TYPE, - /// Span Batch. - Span = SPAN_BATCH_TYPE, -} - -impl From for BatchType { - fn from(val: u8) -> Self { - match val { - SINGLE_BATCH_TYPE => Self::Single, - SPAN_BATCH_TYPE => Self::Span, - _ => panic!("Invalid batch type: {val}"), - } - } -} - -impl From<&[u8]> for BatchType { - fn from(buf: &[u8]) -> Self { - Self::from(buf[0]) - } -} - -impl Encodable for BatchType { - fn encode(&self, out: &mut dyn alloy_rlp::BufMut) { - let val = match self { - Self::Single => SINGLE_BATCH_TYPE, - Self::Span => SPAN_BATCH_TYPE, - }; - val.encode(out); - } -} - -impl Decodable for BatchType { - fn decode(buf: &mut &[u8]) -> alloy_rlp::Result { - let val = u8::decode(buf)?; - Ok(Self::from(val)) - } -} - -#[cfg(test)] -mod test { - use super::*; - use alloc::vec::Vec; - - #[test] - fn test_batch_type_rlp_roundtrip() { - let batch_type = BatchType::Single; - let mut buf = Vec::new(); - batch_type.encode(&mut buf); - let decoded = BatchType::decode(&mut buf.as_slice()).unwrap(); - assert_eq!(batch_type, decoded); - } -} From d6276421cb04ef0f7bed43d72452c0713ed1a9c2 Mon Sep 17 00:00:00 2001 From: refcell Date: Fri, 25 Oct 2024 16:19:12 -0400 Subject: [PATCH 3/3] feat: batch validation trait --- Cargo.toml | 1 + crates/protocol/Cargo.toml | 1 + crates/protocol/src/batch/mod.rs | 3 +++ crates/protocol/src/batch/traits.rs | 25 +++++++++++++++++++++++++ crates/protocol/src/lib.rs | 5 ++++- 5 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 crates/protocol/src/batch/traits.rs diff --git a/Cargo.toml b/Cargo.toml index e7683e61f..19456ba88 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -85,6 +85,7 @@ jsonrpsee-core = "0.24" jsonrpsee-types = "0.24" # misc +async-trait = "0.1.83" cfg-if = "1" spin = { version = "0.9.8", features = ["mutex"] } derive_more = { version = "1.0", default-features = false } diff --git a/crates/protocol/Cargo.toml b/crates/protocol/Cargo.toml index 59d66138f..1538e1929 100644 --- a/crates/protocol/Cargo.toml +++ b/crates/protocol/Cargo.toml @@ -27,6 +27,7 @@ alloy-consensus.workspace = true # Misc derive_more.workspace = true +async-trait.workspace = true # `arbitrary` feature arbitrary = { workspace = true, features = ["derive"], optional = true } diff --git a/crates/protocol/src/batch/mod.rs b/crates/protocol/src/batch/mod.rs index d29ab9186..3c35a48bd 100644 --- a/crates/protocol/src/batch/mod.rs +++ b/crates/protocol/src/batch/mod.rs @@ -8,3 +8,6 @@ pub use validity::BatchValidity; mod single; pub use single::SingleBatch; + +mod traits; +pub use traits::BatchValidationProvider; diff --git a/crates/protocol/src/batch/traits.rs b/crates/protocol/src/batch/traits.rs new file mode 100644 index 000000000..6ff03db1f --- /dev/null +++ b/crates/protocol/src/batch/traits.rs @@ -0,0 +1,25 @@ +//! Traits for working with protocol types. + +use alloc::{boxed::Box, string::ToString}; +use async_trait::async_trait; +use core::fmt::Display; +use op_alloy_consensus::OpBlock; + +use crate::L2BlockInfo; + +/// Describes the functionality of a data source that fetches safe blocks. +#[async_trait] +pub trait BatchValidationProvider { + /// The error type for the [BatchValidationProvider]. + type Error: Display + ToString; + + /// Returns the [L2BlockInfo] given a block number. + /// + /// Errors if the block does not exist. + async fn l2_block_info_by_number(&mut self, number: u64) -> Result; + + /// Returns the [OpBlock] for a given number. + /// + /// Errors if no block is available for the given block number. + async fn block_by_number(&mut self, number: u64) -> Result; +} diff --git a/crates/protocol/src/lib.rs b/crates/protocol/src/lib.rs index 102af03dc..d1d719e85 100644 --- a/crates/protocol/src/lib.rs +++ b/crates/protocol/src/lib.rs @@ -10,7 +10,10 @@ extern crate alloc; mod batch; -pub use batch::{BatchType, BatchValidity, SingleBatch, SINGLE_BATCH_TYPE, SPAN_BATCH_TYPE}; +pub use batch::{ + BatchType, BatchValidationProvider, BatchValidity, SingleBatch, SINGLE_BATCH_TYPE, + SPAN_BATCH_TYPE, +}; mod block; pub use block::{BlockInfo, FromBlockError, L2BlockInfo};