From fd2bb2d7ff443931887fecf61cdb1108eae8bdf5 Mon Sep 17 00:00:00 2001 From: itamar Date: Wed, 18 Sep 2024 16:58:21 -0400 Subject: [PATCH 1/5] add auctioneer draft move optimistic_block to sequencerblock remove prev_rollup_block_hash from BaseBlock move bundle service to executionapis request type for baseblock separate bundle service into OptimisticExecutionService and BundleService --- .../src/generated/astria.bundle.v1alpha1.rs | 747 ++++++++++++++++++ .../generated/astria.bundle.v1alpha1.serde.rs | 559 +++++++++++++ .../astria.sequencerblock.v1alpha1.rs | 484 ++++++++++++ .../astria.sequencerblock.v1alpha1.serde.rs | 369 +++++++++ .../astria/bundle/v1alpha1/bundle.proto | 67 ++ .../v1alpha1/optimistic_block.proto | 35 + 6 files changed, 2261 insertions(+) create mode 100644 crates/astria-core/src/generated/astria.bundle.v1alpha1.rs create mode 100644 crates/astria-core/src/generated/astria.bundle.v1alpha1.serde.rs create mode 100644 proto/executionapis/astria/bundle/v1alpha1/bundle.proto create mode 100644 proto/sequencerblockapis/astria/sequencerblock/v1alpha1/optimistic_block.proto diff --git a/crates/astria-core/src/generated/astria.bundle.v1alpha1.rs b/crates/astria-core/src/generated/astria.bundle.v1alpha1.rs new file mode 100644 index 0000000000..70380401fb --- /dev/null +++ b/crates/astria-core/src/generated/astria.bundle.v1alpha1.rs @@ -0,0 +1,747 @@ +/// The "BaseBlock" is the information needed to simulate bundles on top of +/// a Sequencer block which may not have been committed yet. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct BaseBlock { + /// This is the block hash for the proposed block. + #[prost(bytes = "bytes", tag = "1")] + pub sequencer_block_hash: ::prost::bytes::Bytes, + /// List of transactions to include in the new block. + #[prost(message, repeated, tag = "2")] + pub transactions: ::prost::alloc::vec::Vec< + super::super::sequencerblock::v1alpha1::RollupData, + >, + /// Timestamp to be used for new block. + #[prost(message, optional, tag = "3")] + pub timestamp: ::core::option::Option<::pbjson_types::Timestamp>, +} +impl ::prost::Name for BaseBlock { + const NAME: &'static str = "BaseBlock"; + const PACKAGE: &'static str = "astria.bundle.v1alpha1"; + fn full_name() -> ::prost::alloc::string::String { + ::prost::alloc::format!("astria.bundle.v1alpha1.{}", Self::NAME) + } +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct StreamExecuteOptimisticBlockRequest { + #[prost(message, optional, tag = "1")] + pub block: ::core::option::Option, +} +impl ::prost::Name for StreamExecuteOptimisticBlockRequest { + const NAME: &'static str = "StreamExecuteOptimisticBlockRequest"; + const PACKAGE: &'static str = "astria.bundle.v1alpha1"; + fn full_name() -> ::prost::alloc::string::String { + ::prost::alloc::format!("astria.bundle.v1alpha1.{}", Self::NAME) + } +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct StreamExecuteOptimisticBlockResponse { + /// Metadata identifying the block resulting from executing a block. Includes number, hash, + /// parent hash and timestamp. + #[prost(message, optional, tag = "1")] + pub block: ::core::option::Option, + /// The base_sequencer_block_hash is the hash from the base sequencer block this block + /// is based on. This is used to associate an optimistic execution result with the hash + /// received once a sequencer block is committed. + #[prost(bytes = "bytes", tag = "2")] + pub base_sequencer_block_hash: ::prost::bytes::Bytes, +} +impl ::prost::Name for StreamExecuteOptimisticBlockResponse { + const NAME: &'static str = "StreamExecuteOptimisticBlockResponse"; + const PACKAGE: &'static str = "astria.bundle.v1alpha1"; + fn full_name() -> ::prost::alloc::string::String { + ::prost::alloc::format!("astria.bundle.v1alpha1.{}", Self::NAME) + } +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct StreamBundlesRequest {} +impl ::prost::Name for StreamBundlesRequest { + const NAME: &'static str = "StreamBundlesRequest"; + const PACKAGE: &'static str = "astria.bundle.v1alpha1"; + fn full_name() -> ::prost::alloc::string::String { + ::prost::alloc::format!("astria.bundle.v1alpha1.{}", Self::NAME) + } +} +/// Information for the bundle submitter to know how to submit the bundle. +/// The fee and base_sequencer_block_hash are not necessarily strictly necessary +/// it allows for the case where the server doesn't always send the highest fee +/// bundles after the previous but could just stream any confirmed bundles. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Bundle { + /// The fee that can be expected to be received for submitting this bundle. + /// This allows the bundle producer to stream any confirmed bundles they would be ok + /// with submitting. Used to avoid race conditions in received bundle packets. Could + /// also be used by a bundle submitter to allow multiple entities to submit bundles. + #[prost(uint64, tag = "1")] + pub fee: u64, + /// The byte list of transactions to be included. + #[prost(bytes = "bytes", repeated, tag = "2")] + pub transactions: ::prost::alloc::vec::Vec<::prost::bytes::Bytes>, + /// The base_sequencer_block_hash is the hash from the base block this bundle + /// is based on. This is used to verify that the bundle is based on the correct + /// Sequencer block. + #[prost(bytes = "bytes", tag = "3")] + pub base_sequencer_block_hash: ::prost::bytes::Bytes, + /// The hash of previous rollup block, on top of which the bundle will be executed as ToB. + #[prost(bytes = "bytes", tag = "4")] + pub prev_rollup_block_hash: ::prost::bytes::Bytes, +} +impl ::prost::Name for Bundle { + const NAME: &'static str = "Bundle"; + const PACKAGE: &'static str = "astria.bundle.v1alpha1"; + fn full_name() -> ::prost::alloc::string::String { + ::prost::alloc::format!("astria.bundle.v1alpha1.{}", Self::NAME) + } +} +/// Generated client implementations. +#[cfg(feature = "client")] +pub mod optimistic_execution_service_client { + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] + use tonic::codegen::*; + use tonic::codegen::http::Uri; + #[derive(Debug, Clone)] + pub struct OptimisticExecutionServiceClient { + inner: tonic::client::Grpc, + } + impl OptimisticExecutionServiceClient { + /// Attempt to create a new client by connecting to a given endpoint. + pub async fn connect(dst: D) -> Result + where + D: TryInto, + D::Error: Into, + { + let conn = tonic::transport::Endpoint::new(dst)?.connect().await?; + Ok(Self::new(conn)) + } + } + impl OptimisticExecutionServiceClient + where + T: tonic::client::GrpcService, + T::Error: Into, + T::ResponseBody: Body + Send + 'static, + ::Error: Into + Send, + { + pub fn new(inner: T) -> Self { + let inner = tonic::client::Grpc::new(inner); + Self { inner } + } + pub fn with_origin(inner: T, origin: Uri) -> Self { + let inner = tonic::client::Grpc::with_origin(inner, origin); + Self { inner } + } + pub fn with_interceptor( + inner: T, + interceptor: F, + ) -> OptimisticExecutionServiceClient> + where + F: tonic::service::Interceptor, + T::ResponseBody: Default, + T: tonic::codegen::Service< + http::Request, + Response = http::Response< + >::ResponseBody, + >, + >, + , + >>::Error: Into + Send + Sync, + { + OptimisticExecutionServiceClient::new( + InterceptedService::new(inner, interceptor), + ) + } + /// Compress requests with the given encoding. + /// + /// This requires the server to support it otherwise it might respond with an + /// error. + #[must_use] + pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.inner = self.inner.send_compressed(encoding); + self + } + /// Enable decompressing responses. + #[must_use] + pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.inner = self.inner.accept_compressed(encoding); + self + } + /// Limits the maximum size of a decoded message. + /// + /// Default: `4MB` + #[must_use] + pub fn max_decoding_message_size(mut self, limit: usize) -> Self { + self.inner = self.inner.max_decoding_message_size(limit); + self + } + /// Limits the maximum size of an encoded message. + /// + /// Default: `usize::MAX` + #[must_use] + pub fn max_encoding_message_size(mut self, limit: usize) -> Self { + self.inner = self.inner.max_encoding_message_size(limit); + self + } + /// Stream blocks from the Auctioneer to Geth for optimistic execution. Geth will stream back + /// metadata from the executed blocks. + pub async fn stream_execute_optimistic_block( + &mut self, + request: impl tonic::IntoStreamingRequest< + Message = super::StreamExecuteOptimisticBlockRequest, + >, + ) -> std::result::Result< + tonic::Response< + tonic::codec::Streaming, + >, + tonic::Status, + > { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::new( + tonic::Code::Unknown, + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/astria.bundle.v1alpha1.OptimisticExecutionService/StreamExecuteOptimisticBlock", + ); + let mut req = request.into_streaming_request(); + req.extensions_mut() + .insert( + GrpcMethod::new( + "astria.bundle.v1alpha1.OptimisticExecutionService", + "StreamExecuteOptimisticBlock", + ), + ); + self.inner.streaming(req, path, codec).await + } + } +} +/// Generated client implementations. +#[cfg(feature = "client")] +pub mod bundle_service_client { + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] + use tonic::codegen::*; + use tonic::codegen::http::Uri; + #[derive(Debug, Clone)] + pub struct BundleServiceClient { + inner: tonic::client::Grpc, + } + impl BundleServiceClient { + /// Attempt to create a new client by connecting to a given endpoint. + pub async fn connect(dst: D) -> Result + where + D: TryInto, + D::Error: Into, + { + let conn = tonic::transport::Endpoint::new(dst)?.connect().await?; + Ok(Self::new(conn)) + } + } + impl BundleServiceClient + where + T: tonic::client::GrpcService, + T::Error: Into, + T::ResponseBody: Body + Send + 'static, + ::Error: Into + Send, + { + pub fn new(inner: T) -> Self { + let inner = tonic::client::Grpc::new(inner); + Self { inner } + } + pub fn with_origin(inner: T, origin: Uri) -> Self { + let inner = tonic::client::Grpc::with_origin(inner, origin); + Self { inner } + } + pub fn with_interceptor( + inner: T, + interceptor: F, + ) -> BundleServiceClient> + where + F: tonic::service::Interceptor, + T::ResponseBody: Default, + T: tonic::codegen::Service< + http::Request, + Response = http::Response< + >::ResponseBody, + >, + >, + , + >>::Error: Into + Send + Sync, + { + BundleServiceClient::new(InterceptedService::new(inner, interceptor)) + } + /// Compress requests with the given encoding. + /// + /// This requires the server to support it otherwise it might respond with an + /// error. + #[must_use] + pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.inner = self.inner.send_compressed(encoding); + self + } + /// Enable decompressing responses. + #[must_use] + pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.inner = self.inner.accept_compressed(encoding); + self + } + /// Limits the maximum size of a decoded message. + /// + /// Default: `4MB` + #[must_use] + pub fn max_decoding_message_size(mut self, limit: usize) -> Self { + self.inner = self.inner.max_decoding_message_size(limit); + self + } + /// Limits the maximum size of an encoded message. + /// + /// Default: `usize::MAX` + #[must_use] + pub fn max_encoding_message_size(mut self, limit: usize) -> Self { + self.inner = self.inner.max_encoding_message_size(limit); + self + } + /// A bundle submitter requests bundles given a new optimistic Sequencer block, + /// and receives a stream of potential bundles for submission, until either a timeout + /// or the connection is closed by the client. + pub async fn stream_bundles( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result< + tonic::Response>, + tonic::Status, + > { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::new( + tonic::Code::Unknown, + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/astria.bundle.v1alpha1.BundleService/StreamBundles", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert( + GrpcMethod::new( + "astria.bundle.v1alpha1.BundleService", + "StreamBundles", + ), + ); + self.inner.server_streaming(req, path, codec).await + } + } +} +/// Generated server implementations. +#[cfg(feature = "server")] +pub mod optimistic_execution_service_server { + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] + use tonic::codegen::*; + /// Generated trait containing gRPC methods that should be implemented for use with OptimisticExecutionServiceServer. + #[async_trait] + pub trait OptimisticExecutionService: Send + Sync + 'static { + /// Server streaming response type for the StreamExecuteOptimisticBlock method. + type StreamExecuteOptimisticBlockStream: tonic::codegen::tokio_stream::Stream< + Item = std::result::Result< + super::StreamExecuteOptimisticBlockResponse, + tonic::Status, + >, + > + + Send + + 'static; + /// Stream blocks from the Auctioneer to Geth for optimistic execution. Geth will stream back + /// metadata from the executed blocks. + async fn stream_execute_optimistic_block( + self: std::sync::Arc, + request: tonic::Request< + tonic::Streaming, + >, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + >; + } + #[derive(Debug)] + pub struct OptimisticExecutionServiceServer { + inner: _Inner, + accept_compression_encodings: EnabledCompressionEncodings, + send_compression_encodings: EnabledCompressionEncodings, + max_decoding_message_size: Option, + max_encoding_message_size: Option, + } + struct _Inner(Arc); + impl OptimisticExecutionServiceServer { + pub fn new(inner: T) -> Self { + Self::from_arc(Arc::new(inner)) + } + pub fn from_arc(inner: Arc) -> Self { + let inner = _Inner(inner); + Self { + inner, + accept_compression_encodings: Default::default(), + send_compression_encodings: Default::default(), + max_decoding_message_size: None, + max_encoding_message_size: None, + } + } + pub fn with_interceptor( + inner: T, + interceptor: F, + ) -> InterceptedService + where + F: tonic::service::Interceptor, + { + InterceptedService::new(Self::new(inner), interceptor) + } + /// Enable decompressing requests with the given encoding. + #[must_use] + pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.accept_compression_encodings.enable(encoding); + self + } + /// Compress responses with the given encoding, if the client supports it. + #[must_use] + pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.send_compression_encodings.enable(encoding); + self + } + /// Limits the maximum size of a decoded message. + /// + /// Default: `4MB` + #[must_use] + pub fn max_decoding_message_size(mut self, limit: usize) -> Self { + self.max_decoding_message_size = Some(limit); + self + } + /// Limits the maximum size of an encoded message. + /// + /// Default: `usize::MAX` + #[must_use] + pub fn max_encoding_message_size(mut self, limit: usize) -> Self { + self.max_encoding_message_size = Some(limit); + self + } + } + impl tonic::codegen::Service> + for OptimisticExecutionServiceServer + where + T: OptimisticExecutionService, + B: Body + Send + 'static, + B::Error: Into + Send + 'static, + { + type Response = http::Response; + type Error = std::convert::Infallible; + type Future = BoxFuture; + fn poll_ready( + &mut self, + _cx: &mut Context<'_>, + ) -> Poll> { + Poll::Ready(Ok(())) + } + fn call(&mut self, req: http::Request) -> Self::Future { + let inner = self.inner.clone(); + match req.uri().path() { + "/astria.bundle.v1alpha1.OptimisticExecutionService/StreamExecuteOptimisticBlock" => { + #[allow(non_camel_case_types)] + struct StreamExecuteOptimisticBlockSvc< + T: OptimisticExecutionService, + >( + pub Arc, + ); + impl< + T: OptimisticExecutionService, + > tonic::server::StreamingService< + super::StreamExecuteOptimisticBlockRequest, + > for StreamExecuteOptimisticBlockSvc { + type Response = super::StreamExecuteOptimisticBlockResponse; + type ResponseStream = T::StreamExecuteOptimisticBlockStream; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request< + tonic::Streaming, + >, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::stream_execute_optimistic_block( + inner, + request, + ) + .await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let inner = inner.0; + let method = StreamExecuteOptimisticBlockSvc(inner); + let codec = tonic::codec::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.streaming(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + _ => { + Box::pin(async move { + Ok( + http::Response::builder() + .status(200) + .header("grpc-status", "12") + .header("content-type", "application/grpc") + .body(empty_body()) + .unwrap(), + ) + }) + } + } + } + } + impl Clone for OptimisticExecutionServiceServer { + fn clone(&self) -> Self { + let inner = self.inner.clone(); + Self { + inner, + accept_compression_encodings: self.accept_compression_encodings, + send_compression_encodings: self.send_compression_encodings, + max_decoding_message_size: self.max_decoding_message_size, + max_encoding_message_size: self.max_encoding_message_size, + } + } + } + impl Clone for _Inner { + fn clone(&self) -> Self { + Self(Arc::clone(&self.0)) + } + } + impl std::fmt::Debug for _Inner { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{:?}", self.0) + } + } + impl tonic::server::NamedService + for OptimisticExecutionServiceServer { + const NAME: &'static str = "astria.bundle.v1alpha1.OptimisticExecutionService"; + } +} +/// Generated server implementations. +#[cfg(feature = "server")] +pub mod bundle_service_server { + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] + use tonic::codegen::*; + /// Generated trait containing gRPC methods that should be implemented for use with BundleServiceServer. + #[async_trait] + pub trait BundleService: Send + Sync + 'static { + /// Server streaming response type for the StreamBundles method. + type StreamBundlesStream: tonic::codegen::tokio_stream::Stream< + Item = std::result::Result, + > + + Send + + 'static; + /// A bundle submitter requests bundles given a new optimistic Sequencer block, + /// and receives a stream of potential bundles for submission, until either a timeout + /// or the connection is closed by the client. + async fn stream_bundles( + self: std::sync::Arc, + request: tonic::Request, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + >; + } + #[derive(Debug)] + pub struct BundleServiceServer { + inner: _Inner, + accept_compression_encodings: EnabledCompressionEncodings, + send_compression_encodings: EnabledCompressionEncodings, + max_decoding_message_size: Option, + max_encoding_message_size: Option, + } + struct _Inner(Arc); + impl BundleServiceServer { + pub fn new(inner: T) -> Self { + Self::from_arc(Arc::new(inner)) + } + pub fn from_arc(inner: Arc) -> Self { + let inner = _Inner(inner); + Self { + inner, + accept_compression_encodings: Default::default(), + send_compression_encodings: Default::default(), + max_decoding_message_size: None, + max_encoding_message_size: None, + } + } + pub fn with_interceptor( + inner: T, + interceptor: F, + ) -> InterceptedService + where + F: tonic::service::Interceptor, + { + InterceptedService::new(Self::new(inner), interceptor) + } + /// Enable decompressing requests with the given encoding. + #[must_use] + pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.accept_compression_encodings.enable(encoding); + self + } + /// Compress responses with the given encoding, if the client supports it. + #[must_use] + pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.send_compression_encodings.enable(encoding); + self + } + /// Limits the maximum size of a decoded message. + /// + /// Default: `4MB` + #[must_use] + pub fn max_decoding_message_size(mut self, limit: usize) -> Self { + self.max_decoding_message_size = Some(limit); + self + } + /// Limits the maximum size of an encoded message. + /// + /// Default: `usize::MAX` + #[must_use] + pub fn max_encoding_message_size(mut self, limit: usize) -> Self { + self.max_encoding_message_size = Some(limit); + self + } + } + impl tonic::codegen::Service> for BundleServiceServer + where + T: BundleService, + B: Body + Send + 'static, + B::Error: Into + Send + 'static, + { + type Response = http::Response; + type Error = std::convert::Infallible; + type Future = BoxFuture; + fn poll_ready( + &mut self, + _cx: &mut Context<'_>, + ) -> Poll> { + Poll::Ready(Ok(())) + } + fn call(&mut self, req: http::Request) -> Self::Future { + let inner = self.inner.clone(); + match req.uri().path() { + "/astria.bundle.v1alpha1.BundleService/StreamBundles" => { + #[allow(non_camel_case_types)] + struct StreamBundlesSvc(pub Arc); + impl< + T: BundleService, + > tonic::server::ServerStreamingService + for StreamBundlesSvc { + type Response = super::Bundle; + type ResponseStream = T::StreamBundlesStream; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::stream_bundles(inner, request).await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let inner = inner.0; + let method = StreamBundlesSvc(inner); + let codec = tonic::codec::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.server_streaming(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + _ => { + Box::pin(async move { + Ok( + http::Response::builder() + .status(200) + .header("grpc-status", "12") + .header("content-type", "application/grpc") + .body(empty_body()) + .unwrap(), + ) + }) + } + } + } + } + impl Clone for BundleServiceServer { + fn clone(&self) -> Self { + let inner = self.inner.clone(); + Self { + inner, + accept_compression_encodings: self.accept_compression_encodings, + send_compression_encodings: self.send_compression_encodings, + max_decoding_message_size: self.max_decoding_message_size, + max_encoding_message_size: self.max_encoding_message_size, + } + } + } + impl Clone for _Inner { + fn clone(&self) -> Self { + Self(Arc::clone(&self.0)) + } + } + impl std::fmt::Debug for _Inner { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{:?}", self.0) + } + } + impl tonic::server::NamedService for BundleServiceServer { + const NAME: &'static str = "astria.bundle.v1alpha1.BundleService"; + } +} diff --git a/crates/astria-core/src/generated/astria.bundle.v1alpha1.serde.rs b/crates/astria-core/src/generated/astria.bundle.v1alpha1.serde.rs new file mode 100644 index 0000000000..dab3fd07a2 --- /dev/null +++ b/crates/astria-core/src/generated/astria.bundle.v1alpha1.serde.rs @@ -0,0 +1,559 @@ +impl serde::Serialize for BaseBlock { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if !self.sequencer_block_hash.is_empty() { + len += 1; + } + if !self.transactions.is_empty() { + len += 1; + } + if self.timestamp.is_some() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("astria.bundle.v1alpha1.BaseBlock", len)?; + if !self.sequencer_block_hash.is_empty() { + #[allow(clippy::needless_borrow)] + struct_ser.serialize_field("sequencerBlockHash", pbjson::private::base64::encode(&self.sequencer_block_hash).as_str())?; + } + if !self.transactions.is_empty() { + struct_ser.serialize_field("transactions", &self.transactions)?; + } + if let Some(v) = self.timestamp.as_ref() { + struct_ser.serialize_field("timestamp", v)?; + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for BaseBlock { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "sequencer_block_hash", + "sequencerBlockHash", + "transactions", + "timestamp", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + SequencerBlockHash, + Transactions, + Timestamp, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "sequencerBlockHash" | "sequencer_block_hash" => Ok(GeneratedField::SequencerBlockHash), + "transactions" => Ok(GeneratedField::Transactions), + "timestamp" => Ok(GeneratedField::Timestamp), + _ => Err(serde::de::Error::unknown_field(value, FIELDS)), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = BaseBlock; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct astria.bundle.v1alpha1.BaseBlock") + } + + fn visit_map(self, mut map_: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut sequencer_block_hash__ = None; + let mut transactions__ = None; + let mut timestamp__ = None; + while let Some(k) = map_.next_key()? { + match k { + GeneratedField::SequencerBlockHash => { + if sequencer_block_hash__.is_some() { + return Err(serde::de::Error::duplicate_field("sequencerBlockHash")); + } + sequencer_block_hash__ = + Some(map_.next_value::<::pbjson::private::BytesDeserialize<_>>()?.0) + ; + } + GeneratedField::Transactions => { + if transactions__.is_some() { + return Err(serde::de::Error::duplicate_field("transactions")); + } + transactions__ = Some(map_.next_value()?); + } + GeneratedField::Timestamp => { + if timestamp__.is_some() { + return Err(serde::de::Error::duplicate_field("timestamp")); + } + timestamp__ = map_.next_value()?; + } + } + } + Ok(BaseBlock { + sequencer_block_hash: sequencer_block_hash__.unwrap_or_default(), + transactions: transactions__.unwrap_or_default(), + timestamp: timestamp__, + }) + } + } + deserializer.deserialize_struct("astria.bundle.v1alpha1.BaseBlock", FIELDS, GeneratedVisitor) + } +} +impl serde::Serialize for Bundle { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if self.fee != 0 { + len += 1; + } + if !self.transactions.is_empty() { + len += 1; + } + if !self.base_sequencer_block_hash.is_empty() { + len += 1; + } + if !self.prev_rollup_block_hash.is_empty() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("astria.bundle.v1alpha1.Bundle", len)?; + if self.fee != 0 { + #[allow(clippy::needless_borrow)] + struct_ser.serialize_field("fee", ToString::to_string(&self.fee).as_str())?; + } + if !self.transactions.is_empty() { + struct_ser.serialize_field("transactions", &self.transactions.iter().map(pbjson::private::base64::encode).collect::>())?; + } + if !self.base_sequencer_block_hash.is_empty() { + #[allow(clippy::needless_borrow)] + struct_ser.serialize_field("baseSequencerBlockHash", pbjson::private::base64::encode(&self.base_sequencer_block_hash).as_str())?; + } + if !self.prev_rollup_block_hash.is_empty() { + #[allow(clippy::needless_borrow)] + struct_ser.serialize_field("prevRollupBlockHash", pbjson::private::base64::encode(&self.prev_rollup_block_hash).as_str())?; + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for Bundle { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "fee", + "transactions", + "base_sequencer_block_hash", + "baseSequencerBlockHash", + "prev_rollup_block_hash", + "prevRollupBlockHash", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + Fee, + Transactions, + BaseSequencerBlockHash, + PrevRollupBlockHash, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "fee" => Ok(GeneratedField::Fee), + "transactions" => Ok(GeneratedField::Transactions), + "baseSequencerBlockHash" | "base_sequencer_block_hash" => Ok(GeneratedField::BaseSequencerBlockHash), + "prevRollupBlockHash" | "prev_rollup_block_hash" => Ok(GeneratedField::PrevRollupBlockHash), + _ => Err(serde::de::Error::unknown_field(value, FIELDS)), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = Bundle; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct astria.bundle.v1alpha1.Bundle") + } + + fn visit_map(self, mut map_: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut fee__ = None; + let mut transactions__ = None; + let mut base_sequencer_block_hash__ = None; + let mut prev_rollup_block_hash__ = None; + while let Some(k) = map_.next_key()? { + match k { + GeneratedField::Fee => { + if fee__.is_some() { + return Err(serde::de::Error::duplicate_field("fee")); + } + fee__ = + Some(map_.next_value::<::pbjson::private::NumberDeserialize<_>>()?.0) + ; + } + GeneratedField::Transactions => { + if transactions__.is_some() { + return Err(serde::de::Error::duplicate_field("transactions")); + } + transactions__ = + Some(map_.next_value::>>()? + .into_iter().map(|x| x.0).collect()) + ; + } + GeneratedField::BaseSequencerBlockHash => { + if base_sequencer_block_hash__.is_some() { + return Err(serde::de::Error::duplicate_field("baseSequencerBlockHash")); + } + base_sequencer_block_hash__ = + Some(map_.next_value::<::pbjson::private::BytesDeserialize<_>>()?.0) + ; + } + GeneratedField::PrevRollupBlockHash => { + if prev_rollup_block_hash__.is_some() { + return Err(serde::de::Error::duplicate_field("prevRollupBlockHash")); + } + prev_rollup_block_hash__ = + Some(map_.next_value::<::pbjson::private::BytesDeserialize<_>>()?.0) + ; + } + } + } + Ok(Bundle { + fee: fee__.unwrap_or_default(), + transactions: transactions__.unwrap_or_default(), + base_sequencer_block_hash: base_sequencer_block_hash__.unwrap_or_default(), + prev_rollup_block_hash: prev_rollup_block_hash__.unwrap_or_default(), + }) + } + } + deserializer.deserialize_struct("astria.bundle.v1alpha1.Bundle", FIELDS, GeneratedVisitor) + } +} +impl serde::Serialize for StreamBundlesRequest { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let len = 0; + let struct_ser = serializer.serialize_struct("astria.bundle.v1alpha1.StreamBundlesRequest", len)?; + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for StreamBundlesRequest { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + Err(serde::de::Error::unknown_field(value, FIELDS)) + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = StreamBundlesRequest; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct astria.bundle.v1alpha1.StreamBundlesRequest") + } + + fn visit_map(self, mut map_: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + while map_.next_key::()?.is_some() { + let _ = map_.next_value::()?; + } + Ok(StreamBundlesRequest { + }) + } + } + deserializer.deserialize_struct("astria.bundle.v1alpha1.StreamBundlesRequest", FIELDS, GeneratedVisitor) + } +} +impl serde::Serialize for StreamExecuteOptimisticBlockRequest { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if self.block.is_some() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("astria.bundle.v1alpha1.StreamExecuteOptimisticBlockRequest", len)?; + if let Some(v) = self.block.as_ref() { + struct_ser.serialize_field("block", v)?; + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for StreamExecuteOptimisticBlockRequest { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "block", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + Block, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "block" => Ok(GeneratedField::Block), + _ => Err(serde::de::Error::unknown_field(value, FIELDS)), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = StreamExecuteOptimisticBlockRequest; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct astria.bundle.v1alpha1.StreamExecuteOptimisticBlockRequest") + } + + fn visit_map(self, mut map_: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut block__ = None; + while let Some(k) = map_.next_key()? { + match k { + GeneratedField::Block => { + if block__.is_some() { + return Err(serde::de::Error::duplicate_field("block")); + } + block__ = map_.next_value()?; + } + } + } + Ok(StreamExecuteOptimisticBlockRequest { + block: block__, + }) + } + } + deserializer.deserialize_struct("astria.bundle.v1alpha1.StreamExecuteOptimisticBlockRequest", FIELDS, GeneratedVisitor) + } +} +impl serde::Serialize for StreamExecuteOptimisticBlockResponse { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if self.block.is_some() { + len += 1; + } + if !self.base_sequencer_block_hash.is_empty() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("astria.bundle.v1alpha1.StreamExecuteOptimisticBlockResponse", len)?; + if let Some(v) = self.block.as_ref() { + struct_ser.serialize_field("block", v)?; + } + if !self.base_sequencer_block_hash.is_empty() { + #[allow(clippy::needless_borrow)] + struct_ser.serialize_field("baseSequencerBlockHash", pbjson::private::base64::encode(&self.base_sequencer_block_hash).as_str())?; + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for StreamExecuteOptimisticBlockResponse { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "block", + "base_sequencer_block_hash", + "baseSequencerBlockHash", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + Block, + BaseSequencerBlockHash, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "block" => Ok(GeneratedField::Block), + "baseSequencerBlockHash" | "base_sequencer_block_hash" => Ok(GeneratedField::BaseSequencerBlockHash), + _ => Err(serde::de::Error::unknown_field(value, FIELDS)), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = StreamExecuteOptimisticBlockResponse; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct astria.bundle.v1alpha1.StreamExecuteOptimisticBlockResponse") + } + + fn visit_map(self, mut map_: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut block__ = None; + let mut base_sequencer_block_hash__ = None; + while let Some(k) = map_.next_key()? { + match k { + GeneratedField::Block => { + if block__.is_some() { + return Err(serde::de::Error::duplicate_field("block")); + } + block__ = map_.next_value()?; + } + GeneratedField::BaseSequencerBlockHash => { + if base_sequencer_block_hash__.is_some() { + return Err(serde::de::Error::duplicate_field("baseSequencerBlockHash")); + } + base_sequencer_block_hash__ = + Some(map_.next_value::<::pbjson::private::BytesDeserialize<_>>()?.0) + ; + } + } + } + Ok(StreamExecuteOptimisticBlockResponse { + block: block__, + base_sequencer_block_hash: base_sequencer_block_hash__.unwrap_or_default(), + }) + } + } + deserializer.deserialize_struct("astria.bundle.v1alpha1.StreamExecuteOptimisticBlockResponse", FIELDS, GeneratedVisitor) + } +} diff --git a/crates/astria-core/src/generated/astria.sequencerblock.v1alpha1.rs b/crates/astria-core/src/generated/astria.sequencerblock.v1alpha1.rs index 56385a3ca7..4c42a1cb95 100644 --- a/crates/astria-core/src/generated/astria.sequencerblock.v1alpha1.rs +++ b/crates/astria-core/src/generated/astria.sequencerblock.v1alpha1.rs @@ -330,6 +330,490 @@ impl ::prost::Name for SubmittedMetadata { } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] +pub struct StreamBlockCommitmentsRequest {} +impl ::prost::Name for StreamBlockCommitmentsRequest { + const NAME: &'static str = "StreamBlockCommitmentsRequest"; + const PACKAGE: &'static str = "astria.sequencerblock.v1alpha1"; + fn full_name() -> ::prost::alloc::string::String { + ::prost::alloc::format!("astria.sequencerblock.v1alpha1.{}", Self::NAME) + } +} +/// Identifying metadata for blocks that have been successfully committed in the Sequencer. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SequencerBlockCommit { + /// Height of the sequencer block that was committed. + #[prost(uint64, tag = "1")] + pub height: u64, + /// Hash of the sequencer block that was committed. + #[prost(bytes = "bytes", tag = "2")] + pub block_hash: ::prost::bytes::Bytes, +} +impl ::prost::Name for SequencerBlockCommit { + const NAME: &'static str = "SequencerBlockCommit"; + const PACKAGE: &'static str = "astria.sequencerblock.v1alpha1"; + fn full_name() -> ::prost::alloc::string::String { + ::prost::alloc::format!("astria.sequencerblock.v1alpha1.{}", Self::NAME) + } +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct StreamOptimisticBlockRequest { + /// The rollup id for which the Sequencer block is being streamed. + #[prost(message, optional, tag = "1")] + pub rollup_id: ::core::option::Option, +} +impl ::prost::Name for StreamOptimisticBlockRequest { + const NAME: &'static str = "StreamOptimisticBlockRequest"; + const PACKAGE: &'static str = "astria.sequencerblock.v1alpha1"; + fn full_name() -> ::prost::alloc::string::String { + ::prost::alloc::format!("astria.sequencerblock.v1alpha1.{}", Self::NAME) + } +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct StreamOptimisticBlockResponse { + /// The optimistic Sequencer block that is being streamed, filtered for the provided rollup id. + #[prost(message, optional, tag = "1")] + pub block: ::core::option::Option, +} +impl ::prost::Name for StreamOptimisticBlockResponse { + const NAME: &'static str = "StreamOptimisticBlockResponse"; + const PACKAGE: &'static str = "astria.sequencerblock.v1alpha1"; + fn full_name() -> ::prost::alloc::string::String { + ::prost::alloc::format!("astria.sequencerblock.v1alpha1.{}", Self::NAME) + } +} +/// Generated client implementations. +#[cfg(feature = "client")] +pub mod optimistic_block_service_client { + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] + use tonic::codegen::*; + use tonic::codegen::http::Uri; + /// The Sequencer will serve this to the aucitoneer + #[derive(Debug, Clone)] + pub struct OptimisticBlockServiceClient { + inner: tonic::client::Grpc, + } + impl OptimisticBlockServiceClient { + /// Attempt to create a new client by connecting to a given endpoint. + pub async fn connect(dst: D) -> Result + where + D: TryInto, + D::Error: Into, + { + let conn = tonic::transport::Endpoint::new(dst)?.connect().await?; + Ok(Self::new(conn)) + } + } + impl OptimisticBlockServiceClient + where + T: tonic::client::GrpcService, + T::Error: Into, + T::ResponseBody: Body + Send + 'static, + ::Error: Into + Send, + { + pub fn new(inner: T) -> Self { + let inner = tonic::client::Grpc::new(inner); + Self { inner } + } + pub fn with_origin(inner: T, origin: Uri) -> Self { + let inner = tonic::client::Grpc::with_origin(inner, origin); + Self { inner } + } + pub fn with_interceptor( + inner: T, + interceptor: F, + ) -> OptimisticBlockServiceClient> + where + F: tonic::service::Interceptor, + T::ResponseBody: Default, + T: tonic::codegen::Service< + http::Request, + Response = http::Response< + >::ResponseBody, + >, + >, + , + >>::Error: Into + Send + Sync, + { + OptimisticBlockServiceClient::new( + InterceptedService::new(inner, interceptor), + ) + } + /// Compress requests with the given encoding. + /// + /// This requires the server to support it otherwise it might respond with an + /// error. + #[must_use] + pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.inner = self.inner.send_compressed(encoding); + self + } + /// Enable decompressing responses. + #[must_use] + pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.inner = self.inner.accept_compressed(encoding); + self + } + /// Limits the maximum size of a decoded message. + /// + /// Default: `4MB` + #[must_use] + pub fn max_decoding_message_size(mut self, limit: usize) -> Self { + self.inner = self.inner.max_decoding_message_size(limit); + self + } + /// Limits the maximum size of an encoded message. + /// + /// Default: `usize::MAX` + #[must_use] + pub fn max_encoding_message_size(mut self, limit: usize) -> Self { + self.inner = self.inner.max_encoding_message_size(limit); + self + } + /// The Sequencer will stream the optimistic Sequencer block (filtered for the provided + /// rollup id) to the Auctioneer. + pub async fn stream_optimistic_block( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result< + tonic::Response< + tonic::codec::Streaming, + >, + tonic::Status, + > { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::new( + tonic::Code::Unknown, + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/astria.sequencerblock.v1alpha1.OptimisticBlockService/StreamOptimisticBlock", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert( + GrpcMethod::new( + "astria.sequencerblock.v1alpha1.OptimisticBlockService", + "StreamOptimisticBlock", + ), + ); + self.inner.server_streaming(req, path, codec).await + } + /// The Sequencer will stream the block commits to the Auctioneer. + pub async fn stream_block_commitments( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result< + tonic::Response>, + tonic::Status, + > { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::new( + tonic::Code::Unknown, + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/astria.sequencerblock.v1alpha1.OptimisticBlockService/StreamBlockCommitments", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert( + GrpcMethod::new( + "astria.sequencerblock.v1alpha1.OptimisticBlockService", + "StreamBlockCommitments", + ), + ); + self.inner.server_streaming(req, path, codec).await + } + } +} +/// Generated server implementations. +#[cfg(feature = "server")] +pub mod optimistic_block_service_server { + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] + use tonic::codegen::*; + /// Generated trait containing gRPC methods that should be implemented for use with OptimisticBlockServiceServer. + #[async_trait] + pub trait OptimisticBlockService: Send + Sync + 'static { + /// Server streaming response type for the StreamOptimisticBlock method. + type StreamOptimisticBlockStream: tonic::codegen::tokio_stream::Stream< + Item = std::result::Result< + super::StreamOptimisticBlockResponse, + tonic::Status, + >, + > + + Send + + 'static; + /// The Sequencer will stream the optimistic Sequencer block (filtered for the provided + /// rollup id) to the Auctioneer. + async fn stream_optimistic_block( + self: std::sync::Arc, + request: tonic::Request, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + >; + /// Server streaming response type for the StreamBlockCommitments method. + type StreamBlockCommitmentsStream: tonic::codegen::tokio_stream::Stream< + Item = std::result::Result, + > + + Send + + 'static; + /// The Sequencer will stream the block commits to the Auctioneer. + async fn stream_block_commitments( + self: std::sync::Arc, + request: tonic::Request, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + >; + } + /// The Sequencer will serve this to the aucitoneer + #[derive(Debug)] + pub struct OptimisticBlockServiceServer { + inner: _Inner, + accept_compression_encodings: EnabledCompressionEncodings, + send_compression_encodings: EnabledCompressionEncodings, + max_decoding_message_size: Option, + max_encoding_message_size: Option, + } + struct _Inner(Arc); + impl OptimisticBlockServiceServer { + pub fn new(inner: T) -> Self { + Self::from_arc(Arc::new(inner)) + } + pub fn from_arc(inner: Arc) -> Self { + let inner = _Inner(inner); + Self { + inner, + accept_compression_encodings: Default::default(), + send_compression_encodings: Default::default(), + max_decoding_message_size: None, + max_encoding_message_size: None, + } + } + pub fn with_interceptor( + inner: T, + interceptor: F, + ) -> InterceptedService + where + F: tonic::service::Interceptor, + { + InterceptedService::new(Self::new(inner), interceptor) + } + /// Enable decompressing requests with the given encoding. + #[must_use] + pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.accept_compression_encodings.enable(encoding); + self + } + /// Compress responses with the given encoding, if the client supports it. + #[must_use] + pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.send_compression_encodings.enable(encoding); + self + } + /// Limits the maximum size of a decoded message. + /// + /// Default: `4MB` + #[must_use] + pub fn max_decoding_message_size(mut self, limit: usize) -> Self { + self.max_decoding_message_size = Some(limit); + self + } + /// Limits the maximum size of an encoded message. + /// + /// Default: `usize::MAX` + #[must_use] + pub fn max_encoding_message_size(mut self, limit: usize) -> Self { + self.max_encoding_message_size = Some(limit); + self + } + } + impl tonic::codegen::Service> + for OptimisticBlockServiceServer + where + T: OptimisticBlockService, + B: Body + Send + 'static, + B::Error: Into + Send + 'static, + { + type Response = http::Response; + type Error = std::convert::Infallible; + type Future = BoxFuture; + fn poll_ready( + &mut self, + _cx: &mut Context<'_>, + ) -> Poll> { + Poll::Ready(Ok(())) + } + fn call(&mut self, req: http::Request) -> Self::Future { + let inner = self.inner.clone(); + match req.uri().path() { + "/astria.sequencerblock.v1alpha1.OptimisticBlockService/StreamOptimisticBlock" => { + #[allow(non_camel_case_types)] + struct StreamOptimisticBlockSvc( + pub Arc, + ); + impl< + T: OptimisticBlockService, + > tonic::server::ServerStreamingService< + super::StreamOptimisticBlockRequest, + > for StreamOptimisticBlockSvc { + type Response = super::StreamOptimisticBlockResponse; + type ResponseStream = T::StreamOptimisticBlockStream; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::stream_optimistic_block( + inner, + request, + ) + .await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let inner = inner.0; + let method = StreamOptimisticBlockSvc(inner); + let codec = tonic::codec::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.server_streaming(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + "/astria.sequencerblock.v1alpha1.OptimisticBlockService/StreamBlockCommitments" => { + #[allow(non_camel_case_types)] + struct StreamBlockCommitmentsSvc( + pub Arc, + ); + impl< + T: OptimisticBlockService, + > tonic::server::ServerStreamingService< + super::StreamBlockCommitmentsRequest, + > for StreamBlockCommitmentsSvc { + type Response = super::SequencerBlockCommit; + type ResponseStream = T::StreamBlockCommitmentsStream; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::stream_block_commitments( + inner, + request, + ) + .await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let inner = inner.0; + let method = StreamBlockCommitmentsSvc(inner); + let codec = tonic::codec::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.server_streaming(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + _ => { + Box::pin(async move { + Ok( + http::Response::builder() + .status(200) + .header("grpc-status", "12") + .header("content-type", "application/grpc") + .body(empty_body()) + .unwrap(), + ) + }) + } + } + } + } + impl Clone for OptimisticBlockServiceServer { + fn clone(&self) -> Self { + let inner = self.inner.clone(); + Self { + inner, + accept_compression_encodings: self.accept_compression_encodings, + send_compression_encodings: self.send_compression_encodings, + max_decoding_message_size: self.max_decoding_message_size, + max_encoding_message_size: self.max_encoding_message_size, + } + } + } + impl Clone for _Inner { + fn clone(&self) -> Self { + Self(Arc::clone(&self.0)) + } + } + impl std::fmt::Debug for _Inner { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{:?}", self.0) + } + } + impl tonic::server::NamedService + for OptimisticBlockServiceServer { + const NAME: &'static str = "astria.sequencerblock.v1alpha1.OptimisticBlockService"; + } +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct GetSequencerBlockRequest { /// The height of the block to retrieve. #[prost(uint64, tag = "1")] diff --git a/crates/astria-core/src/generated/astria.sequencerblock.v1alpha1.serde.rs b/crates/astria-core/src/generated/astria.sequencerblock.v1alpha1.serde.rs index 2a7168de53..c0c74674c7 100644 --- a/crates/astria-core/src/generated/astria.sequencerblock.v1alpha1.serde.rs +++ b/crates/astria-core/src/generated/astria.sequencerblock.v1alpha1.serde.rs @@ -1181,6 +1181,121 @@ impl<'de> serde::Deserialize<'de> for SequencerBlock { deserializer.deserialize_struct("astria.sequencerblock.v1alpha1.SequencerBlock", FIELDS, GeneratedVisitor) } } +impl serde::Serialize for SequencerBlockCommit { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if self.height != 0 { + len += 1; + } + if !self.block_hash.is_empty() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("astria.sequencerblock.v1alpha1.SequencerBlockCommit", len)?; + if self.height != 0 { + #[allow(clippy::needless_borrow)] + struct_ser.serialize_field("height", ToString::to_string(&self.height).as_str())?; + } + if !self.block_hash.is_empty() { + #[allow(clippy::needless_borrow)] + struct_ser.serialize_field("blockHash", pbjson::private::base64::encode(&self.block_hash).as_str())?; + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for SequencerBlockCommit { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "height", + "block_hash", + "blockHash", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + Height, + BlockHash, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "height" => Ok(GeneratedField::Height), + "blockHash" | "block_hash" => Ok(GeneratedField::BlockHash), + _ => Err(serde::de::Error::unknown_field(value, FIELDS)), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = SequencerBlockCommit; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct astria.sequencerblock.v1alpha1.SequencerBlockCommit") + } + + fn visit_map(self, mut map_: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut height__ = None; + let mut block_hash__ = None; + while let Some(k) = map_.next_key()? { + match k { + GeneratedField::Height => { + if height__.is_some() { + return Err(serde::de::Error::duplicate_field("height")); + } + height__ = + Some(map_.next_value::<::pbjson::private::NumberDeserialize<_>>()?.0) + ; + } + GeneratedField::BlockHash => { + if block_hash__.is_some() { + return Err(serde::de::Error::duplicate_field("blockHash")); + } + block_hash__ = + Some(map_.next_value::<::pbjson::private::BytesDeserialize<_>>()?.0) + ; + } + } + } + Ok(SequencerBlockCommit { + height: height__.unwrap_or_default(), + block_hash: block_hash__.unwrap_or_default(), + }) + } + } + deserializer.deserialize_struct("astria.sequencerblock.v1alpha1.SequencerBlockCommit", FIELDS, GeneratedVisitor) + } +} impl serde::Serialize for SequencerBlockHeader { #[allow(deprecated)] fn serialize(&self, serializer: S) -> std::result::Result @@ -1373,6 +1488,260 @@ impl<'de> serde::Deserialize<'de> for SequencerBlockHeader { deserializer.deserialize_struct("astria.sequencerblock.v1alpha1.SequencerBlockHeader", FIELDS, GeneratedVisitor) } } +impl serde::Serialize for StreamBlockCommitmentsRequest { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let len = 0; + let struct_ser = serializer.serialize_struct("astria.sequencerblock.v1alpha1.StreamBlockCommitmentsRequest", len)?; + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for StreamBlockCommitmentsRequest { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + Err(serde::de::Error::unknown_field(value, FIELDS)) + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = StreamBlockCommitmentsRequest; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct astria.sequencerblock.v1alpha1.StreamBlockCommitmentsRequest") + } + + fn visit_map(self, mut map_: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + while map_.next_key::()?.is_some() { + let _ = map_.next_value::()?; + } + Ok(StreamBlockCommitmentsRequest { + }) + } + } + deserializer.deserialize_struct("astria.sequencerblock.v1alpha1.StreamBlockCommitmentsRequest", FIELDS, GeneratedVisitor) + } +} +impl serde::Serialize for StreamOptimisticBlockRequest { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if self.rollup_id.is_some() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("astria.sequencerblock.v1alpha1.StreamOptimisticBlockRequest", len)?; + if let Some(v) = self.rollup_id.as_ref() { + struct_ser.serialize_field("rollupId", v)?; + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for StreamOptimisticBlockRequest { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "rollup_id", + "rollupId", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + RollupId, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "rollupId" | "rollup_id" => Ok(GeneratedField::RollupId), + _ => Err(serde::de::Error::unknown_field(value, FIELDS)), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = StreamOptimisticBlockRequest; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct astria.sequencerblock.v1alpha1.StreamOptimisticBlockRequest") + } + + fn visit_map(self, mut map_: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut rollup_id__ = None; + while let Some(k) = map_.next_key()? { + match k { + GeneratedField::RollupId => { + if rollup_id__.is_some() { + return Err(serde::de::Error::duplicate_field("rollupId")); + } + rollup_id__ = map_.next_value()?; + } + } + } + Ok(StreamOptimisticBlockRequest { + rollup_id: rollup_id__, + }) + } + } + deserializer.deserialize_struct("astria.sequencerblock.v1alpha1.StreamOptimisticBlockRequest", FIELDS, GeneratedVisitor) + } +} +impl serde::Serialize for StreamOptimisticBlockResponse { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if self.block.is_some() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("astria.sequencerblock.v1alpha1.StreamOptimisticBlockResponse", len)?; + if let Some(v) = self.block.as_ref() { + struct_ser.serialize_field("block", v)?; + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for StreamOptimisticBlockResponse { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "block", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + Block, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "block" => Ok(GeneratedField::Block), + _ => Err(serde::de::Error::unknown_field(value, FIELDS)), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = StreamOptimisticBlockResponse; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct astria.sequencerblock.v1alpha1.StreamOptimisticBlockResponse") + } + + fn visit_map(self, mut map_: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut block__ = None; + while let Some(k) = map_.next_key()? { + match k { + GeneratedField::Block => { + if block__.is_some() { + return Err(serde::de::Error::duplicate_field("block")); + } + block__ = map_.next_value()?; + } + } + } + Ok(StreamOptimisticBlockResponse { + block: block__, + }) + } + } + deserializer.deserialize_struct("astria.sequencerblock.v1alpha1.StreamOptimisticBlockResponse", FIELDS, GeneratedVisitor) + } +} impl serde::Serialize for SubmittedMetadata { #[allow(deprecated)] fn serialize(&self, serializer: S) -> std::result::Result diff --git a/proto/executionapis/astria/bundle/v1alpha1/bundle.proto b/proto/executionapis/astria/bundle/v1alpha1/bundle.proto new file mode 100644 index 0000000000..c077f28a0e --- /dev/null +++ b/proto/executionapis/astria/bundle/v1alpha1/bundle.proto @@ -0,0 +1,67 @@ +syntax = "proto3"; + +package astria.bundle.v1alpha1; + +import "astria/execution/v1alpha2/execution.proto"; +import "astria/sequencerblock/v1alpha1/block.proto"; +import "google/protobuf/timestamp.proto"; + +// The "BaseBlock" is the information needed to simulate bundles on top of +// a Sequencer block which may not have been committed yet. +message BaseBlock { + // This is the block hash for the proposed block. + bytes sequencer_block_hash = 1; + // List of transactions to include in the new block. + repeated astria.sequencerblock.v1alpha1.RollupData transactions = 2; + // Timestamp to be used for new block. + google.protobuf.Timestamp timestamp = 3; +} + +message StreamExecuteOptimisticBlockRequest { + BaseBlock block = 1; +} + +message StreamExecuteOptimisticBlockResponse { + // Metadata identifying the block resulting from executing a block. Includes number, hash, + // parent hash and timestamp. + astria.execution.v1alpha2.Block block = 1; + // The base_sequencer_block_hash is the hash from the base sequencer block this block + // is based on. This is used to associate an optimistic execution result with the hash + // received once a sequencer block is committed. + bytes base_sequencer_block_hash = 2; +} + +message StreamBundlesRequest {} + +// Information for the bundle submitter to know how to submit the bundle. +// The fee and base_sequencer_block_hash are not necessarily strictly necessary +// it allows for the case where the server doesn't always send the highest fee +// bundles after the previous but could just stream any confirmed bundles. +message Bundle { + // The fee that can be expected to be received for submitting this bundle. + // This allows the bundle producer to stream any confirmed bundles they would be ok + // with submitting. Used to avoid race conditions in received bundle packets. Could + // also be used by a bundle submitter to allow multiple entities to submit bundles. + uint64 fee = 1; + // The byte list of transactions to be included. + repeated bytes transactions = 2; + // The base_sequencer_block_hash is the hash from the base block this bundle + // is based on. This is used to verify that the bundle is based on the correct + // Sequencer block. + bytes base_sequencer_block_hash = 3; + // The hash of previous rollup block, on top of which the bundle will be executed as ToB. + bytes prev_rollup_block_hash = 4; +} + +service OptimisticExecutionService { + // Stream blocks from the Auctioneer to Geth for optimistic execution. Geth will stream back + // metadata from the executed blocks. + rpc StreamExecuteOptimisticBlock(stream StreamExecuteOptimisticBlockRequest) returns (stream StreamExecuteOptimisticBlockResponse); +} + +service BundleService { + // A bundle submitter requests bundles given a new optimistic Sequencer block, + // and receives a stream of potential bundles for submission, until either a timeout + // or the connection is closed by the client. + rpc StreamBundles(StreamBundlesRequest) returns (stream Bundle); +} diff --git a/proto/sequencerblockapis/astria/sequencerblock/v1alpha1/optimistic_block.proto b/proto/sequencerblockapis/astria/sequencerblock/v1alpha1/optimistic_block.proto new file mode 100644 index 0000000000..02c4ae0c35 --- /dev/null +++ b/proto/sequencerblockapis/astria/sequencerblock/v1alpha1/optimistic_block.proto @@ -0,0 +1,35 @@ +syntax = "proto3"; + +package astria.sequencerblock.v1alpha1; + +import "astria/primitive/v1/types.proto"; +import "astria/sequencerblock/v1alpha1/block.proto"; + +message StreamBlockCommitmentsRequest {} + +// Identifying metadata for blocks that have been successfully committed in the Sequencer. +message SequencerBlockCommit { + // Height of the sequencer block that was committed. + uint64 height = 1; + // Hash of the sequencer block that was committed. + bytes block_hash = 2; +} + +message StreamOptimisticBlockRequest { + // The rollup id for which the Sequencer block is being streamed. + astria.primitive.v1.RollupId rollup_id = 1; +} + +message StreamOptimisticBlockResponse { + // The optimistic Sequencer block that is being streamed, filtered for the provided rollup id. + astria.sequencerblock.v1alpha1.FilteredSequencerBlock block = 1; +} + +// The Sequencer will serve this to the aucitoneer +service OptimisticBlockService { + // The Sequencer will stream the optimistic Sequencer block (filtered for the provided + // rollup id) to the Auctioneer. + rpc StreamOptimisticBlock(StreamOptimisticBlockRequest) returns (stream StreamOptimisticBlockResponse); + // The Sequencer will stream the block commits to the Auctioneer. + rpc StreamBlockCommitments(StreamBlockCommitmentsRequest) returns (stream SequencerBlockCommit); +} From 2bbe4e2b9a5233be5379ebb58396cde8987ec793 Mon Sep 17 00:00:00 2001 From: itamar Date: Wed, 2 Oct 2024 14:00:59 -0400 Subject: [PATCH 2/5] name cleanup --- .../src/generated/astria.bundle.v1alpha1.rs | 115 ++-- .../generated/astria.bundle.v1alpha1.serde.rs | 214 ++++-- .../astria.sequencerblock.v1alpha1.rs | 120 ++-- .../astria.sequencerblock.v1alpha1.serde.rs | 639 ++++++++++-------- .../astria/bundle/v1alpha1/bundle.proto | 16 +- .../v1alpha1/optimistic_block.proto | 14 +- 6 files changed, 673 insertions(+), 445 deletions(-) diff --git a/crates/astria-core/src/generated/astria.bundle.v1alpha1.rs b/crates/astria-core/src/generated/astria.bundle.v1alpha1.rs index 70380401fb..b4ab725ab2 100644 --- a/crates/astria-core/src/generated/astria.bundle.v1alpha1.rs +++ b/crates/astria-core/src/generated/astria.bundle.v1alpha1.rs @@ -24,12 +24,12 @@ impl ::prost::Name for BaseBlock { } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] -pub struct StreamExecuteOptimisticBlockRequest { +pub struct ExecuteOptimisticBlockStreamRequest { #[prost(message, optional, tag = "1")] - pub block: ::core::option::Option, + pub base_block: ::core::option::Option, } -impl ::prost::Name for StreamExecuteOptimisticBlockRequest { - const NAME: &'static str = "StreamExecuteOptimisticBlockRequest"; +impl ::prost::Name for ExecuteOptimisticBlockStreamRequest { + const NAME: &'static str = "ExecuteOptimisticBlockStreamRequest"; const PACKAGE: &'static str = "astria.bundle.v1alpha1"; fn full_name() -> ::prost::alloc::string::String { ::prost::alloc::format!("astria.bundle.v1alpha1.{}", Self::NAME) @@ -37,7 +37,7 @@ impl ::prost::Name for StreamExecuteOptimisticBlockRequest { } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] -pub struct StreamExecuteOptimisticBlockResponse { +pub struct ExecuteOptimisticBlockStreamResponse { /// Metadata identifying the block resulting from executing a block. Includes number, hash, /// parent hash and timestamp. #[prost(message, optional, tag = "1")] @@ -48,8 +48,8 @@ pub struct StreamExecuteOptimisticBlockResponse { #[prost(bytes = "bytes", tag = "2")] pub base_sequencer_block_hash: ::prost::bytes::Bytes, } -impl ::prost::Name for StreamExecuteOptimisticBlockResponse { - const NAME: &'static str = "StreamExecuteOptimisticBlockResponse"; +impl ::prost::Name for ExecuteOptimisticBlockStreamResponse { + const NAME: &'static str = "ExecuteOptimisticBlockStreamResponse"; const PACKAGE: &'static str = "astria.bundle.v1alpha1"; fn full_name() -> ::prost::alloc::string::String { ::prost::alloc::format!("astria.bundle.v1alpha1.{}", Self::NAME) @@ -57,9 +57,9 @@ impl ::prost::Name for StreamExecuteOptimisticBlockResponse { } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] -pub struct StreamBundlesRequest {} -impl ::prost::Name for StreamBundlesRequest { - const NAME: &'static str = "StreamBundlesRequest"; +pub struct GetBundleStreamRequest {} +impl ::prost::Name for GetBundleStreamRequest { + const NAME: &'static str = "GetBundleStreamRequest"; const PACKAGE: &'static str = "astria.bundle.v1alpha1"; fn full_name() -> ::prost::alloc::string::String { ::prost::alloc::format!("astria.bundle.v1alpha1.{}", Self::NAME) @@ -97,6 +97,19 @@ impl ::prost::Name for Bundle { ::prost::alloc::format!("astria.bundle.v1alpha1.{}", Self::NAME) } } +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetBundleStreamResponse { + #[prost(message, optional, tag = "1")] + pub bundle: ::core::option::Option, +} +impl ::prost::Name for GetBundleStreamResponse { + const NAME: &'static str = "GetBundleStreamResponse"; + const PACKAGE: &'static str = "astria.bundle.v1alpha1"; + fn full_name() -> ::prost::alloc::string::String { + ::prost::alloc::format!("astria.bundle.v1alpha1.{}", Self::NAME) + } +} /// Generated client implementations. #[cfg(feature = "client")] pub mod optimistic_execution_service_client { @@ -187,14 +200,14 @@ pub mod optimistic_execution_service_client { } /// Stream blocks from the Auctioneer to Geth for optimistic execution. Geth will stream back /// metadata from the executed blocks. - pub async fn stream_execute_optimistic_block( + pub async fn execute_optimistic_block_stream( &mut self, request: impl tonic::IntoStreamingRequest< - Message = super::StreamExecuteOptimisticBlockRequest, + Message = super::ExecuteOptimisticBlockStreamRequest, >, ) -> std::result::Result< tonic::Response< - tonic::codec::Streaming, + tonic::codec::Streaming, >, tonic::Status, > { @@ -209,14 +222,14 @@ pub mod optimistic_execution_service_client { })?; let codec = tonic::codec::ProstCodec::default(); let path = http::uri::PathAndQuery::from_static( - "/astria.bundle.v1alpha1.OptimisticExecutionService/StreamExecuteOptimisticBlock", + "/astria.bundle.v1alpha1.OptimisticExecutionService/ExecuteOptimisticBlockStream", ); let mut req = request.into_streaming_request(); req.extensions_mut() .insert( GrpcMethod::new( "astria.bundle.v1alpha1.OptimisticExecutionService", - "StreamExecuteOptimisticBlock", + "ExecuteOptimisticBlockStream", ), ); self.inner.streaming(req, path, codec).await @@ -312,11 +325,11 @@ pub mod bundle_service_client { /// A bundle submitter requests bundles given a new optimistic Sequencer block, /// and receives a stream of potential bundles for submission, until either a timeout /// or the connection is closed by the client. - pub async fn stream_bundles( + pub async fn get_bundle_stream( &mut self, - request: impl tonic::IntoRequest, + request: impl tonic::IntoRequest, ) -> std::result::Result< - tonic::Response>, + tonic::Response>, tonic::Status, > { self.inner @@ -330,14 +343,14 @@ pub mod bundle_service_client { })?; let codec = tonic::codec::ProstCodec::default(); let path = http::uri::PathAndQuery::from_static( - "/astria.bundle.v1alpha1.BundleService/StreamBundles", + "/astria.bundle.v1alpha1.BundleService/GetBundleStream", ); let mut req = request.into_request(); req.extensions_mut() .insert( GrpcMethod::new( "astria.bundle.v1alpha1.BundleService", - "StreamBundles", + "GetBundleStream", ), ); self.inner.server_streaming(req, path, codec).await @@ -352,10 +365,10 @@ pub mod optimistic_execution_service_server { /// Generated trait containing gRPC methods that should be implemented for use with OptimisticExecutionServiceServer. #[async_trait] pub trait OptimisticExecutionService: Send + Sync + 'static { - /// Server streaming response type for the StreamExecuteOptimisticBlock method. - type StreamExecuteOptimisticBlockStream: tonic::codegen::tokio_stream::Stream< + /// Server streaming response type for the ExecuteOptimisticBlockStream method. + type ExecuteOptimisticBlockStreamStream: tonic::codegen::tokio_stream::Stream< Item = std::result::Result< - super::StreamExecuteOptimisticBlockResponse, + super::ExecuteOptimisticBlockStreamResponse, tonic::Status, >, > @@ -363,13 +376,13 @@ pub mod optimistic_execution_service_server { + 'static; /// Stream blocks from the Auctioneer to Geth for optimistic execution. Geth will stream back /// metadata from the executed blocks. - async fn stream_execute_optimistic_block( + async fn execute_optimistic_block_stream( self: std::sync::Arc, request: tonic::Request< - tonic::Streaming, + tonic::Streaming, >, ) -> std::result::Result< - tonic::Response, + tonic::Response, tonic::Status, >; } @@ -453,9 +466,9 @@ pub mod optimistic_execution_service_server { fn call(&mut self, req: http::Request) -> Self::Future { let inner = self.inner.clone(); match req.uri().path() { - "/astria.bundle.v1alpha1.OptimisticExecutionService/StreamExecuteOptimisticBlock" => { + "/astria.bundle.v1alpha1.OptimisticExecutionService/ExecuteOptimisticBlockStream" => { #[allow(non_camel_case_types)] - struct StreamExecuteOptimisticBlockSvc< + struct ExecuteOptimisticBlockStreamSvc< T: OptimisticExecutionService, >( pub Arc, @@ -463,10 +476,10 @@ pub mod optimistic_execution_service_server { impl< T: OptimisticExecutionService, > tonic::server::StreamingService< - super::StreamExecuteOptimisticBlockRequest, - > for StreamExecuteOptimisticBlockSvc { - type Response = super::StreamExecuteOptimisticBlockResponse; - type ResponseStream = T::StreamExecuteOptimisticBlockStream; + super::ExecuteOptimisticBlockStreamRequest, + > for ExecuteOptimisticBlockStreamSvc { + type Response = super::ExecuteOptimisticBlockStreamResponse; + type ResponseStream = T::ExecuteOptimisticBlockStreamStream; type Future = BoxFuture< tonic::Response, tonic::Status, @@ -474,12 +487,12 @@ pub mod optimistic_execution_service_server { fn call( &mut self, request: tonic::Request< - tonic::Streaming, + tonic::Streaming, >, ) -> Self::Future { let inner = Arc::clone(&self.0); let fut = async move { - ::stream_execute_optimistic_block( + ::execute_optimistic_block_stream( inner, request, ) @@ -495,7 +508,7 @@ pub mod optimistic_execution_service_server { let inner = self.inner.clone(); let fut = async move { let inner = inner.0; - let method = StreamExecuteOptimisticBlockSvc(inner); + let method = ExecuteOptimisticBlockStreamSvc(inner); let codec = tonic::codec::ProstCodec::default(); let mut grpc = tonic::server::Grpc::new(codec) .apply_compression_config( @@ -561,20 +574,20 @@ pub mod bundle_service_server { /// Generated trait containing gRPC methods that should be implemented for use with BundleServiceServer. #[async_trait] pub trait BundleService: Send + Sync + 'static { - /// Server streaming response type for the StreamBundles method. - type StreamBundlesStream: tonic::codegen::tokio_stream::Stream< - Item = std::result::Result, + /// Server streaming response type for the GetBundleStream method. + type GetBundleStreamStream: tonic::codegen::tokio_stream::Stream< + Item = std::result::Result, > + Send + 'static; /// A bundle submitter requests bundles given a new optimistic Sequencer block, /// and receives a stream of potential bundles for submission, until either a timeout /// or the connection is closed by the client. - async fn stream_bundles( + async fn get_bundle_stream( self: std::sync::Arc, - request: tonic::Request, + request: tonic::Request, ) -> std::result::Result< - tonic::Response, + tonic::Response, tonic::Status, >; } @@ -657,26 +670,28 @@ pub mod bundle_service_server { fn call(&mut self, req: http::Request) -> Self::Future { let inner = self.inner.clone(); match req.uri().path() { - "/astria.bundle.v1alpha1.BundleService/StreamBundles" => { + "/astria.bundle.v1alpha1.BundleService/GetBundleStream" => { #[allow(non_camel_case_types)] - struct StreamBundlesSvc(pub Arc); + struct GetBundleStreamSvc(pub Arc); impl< T: BundleService, - > tonic::server::ServerStreamingService - for StreamBundlesSvc { - type Response = super::Bundle; - type ResponseStream = T::StreamBundlesStream; + > tonic::server::ServerStreamingService< + super::GetBundleStreamRequest, + > for GetBundleStreamSvc { + type Response = super::GetBundleStreamResponse; + type ResponseStream = T::GetBundleStreamStream; type Future = BoxFuture< tonic::Response, tonic::Status, >; fn call( &mut self, - request: tonic::Request, + request: tonic::Request, ) -> Self::Future { let inner = Arc::clone(&self.0); let fut = async move { - ::stream_bundles(inner, request).await + ::get_bundle_stream(inner, request) + .await }; Box::pin(fut) } @@ -688,7 +703,7 @@ pub mod bundle_service_server { let inner = self.inner.clone(); let fut = async move { let inner = inner.0; - let method = StreamBundlesSvc(inner); + let method = GetBundleStreamSvc(inner); let codec = tonic::codec::ProstCodec::default(); let mut grpc = tonic::server::Grpc::new(codec) .apply_compression_config( diff --git a/crates/astria-core/src/generated/astria.bundle.v1alpha1.serde.rs b/crates/astria-core/src/generated/astria.bundle.v1alpha1.serde.rs index dab3fd07a2..0ae7a566fd 100644 --- a/crates/astria-core/src/generated/astria.bundle.v1alpha1.serde.rs +++ b/crates/astria-core/src/generated/astria.bundle.v1alpha1.serde.rs @@ -283,29 +283,38 @@ impl<'de> serde::Deserialize<'de> for Bundle { deserializer.deserialize_struct("astria.bundle.v1alpha1.Bundle", FIELDS, GeneratedVisitor) } } -impl serde::Serialize for StreamBundlesRequest { +impl serde::Serialize for ExecuteOptimisticBlockStreamRequest { #[allow(deprecated)] fn serialize(&self, serializer: S) -> std::result::Result where S: serde::Serializer, { use serde::ser::SerializeStruct; - let len = 0; - let struct_ser = serializer.serialize_struct("astria.bundle.v1alpha1.StreamBundlesRequest", len)?; + let mut len = 0; + if self.base_block.is_some() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("astria.bundle.v1alpha1.ExecuteOptimisticBlockStreamRequest", len)?; + if let Some(v) = self.base_block.as_ref() { + struct_ser.serialize_field("baseBlock", v)?; + } struct_ser.end() } } -impl<'de> serde::Deserialize<'de> for StreamBundlesRequest { +impl<'de> serde::Deserialize<'de> for ExecuteOptimisticBlockStreamRequest { #[allow(deprecated)] fn deserialize(deserializer: D) -> std::result::Result where D: serde::Deserializer<'de>, { const FIELDS: &[&str] = &[ + "base_block", + "baseBlock", ]; #[allow(clippy::enum_variant_names)] enum GeneratedField { + BaseBlock, } impl<'de> serde::Deserialize<'de> for GeneratedField { fn deserialize(deserializer: D) -> std::result::Result @@ -326,7 +335,10 @@ impl<'de> serde::Deserialize<'de> for StreamBundlesRequest { where E: serde::de::Error, { - Err(serde::de::Error::unknown_field(value, FIELDS)) + match value { + "baseBlock" | "base_block" => Ok(GeneratedField::BaseBlock), + _ => Err(serde::de::Error::unknown_field(value, FIELDS)), + } } } deserializer.deserialize_identifier(GeneratedVisitor) @@ -334,27 +346,36 @@ impl<'de> serde::Deserialize<'de> for StreamBundlesRequest { } struct GeneratedVisitor; impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { - type Value = StreamBundlesRequest; + type Value = ExecuteOptimisticBlockStreamRequest; fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - formatter.write_str("struct astria.bundle.v1alpha1.StreamBundlesRequest") + formatter.write_str("struct astria.bundle.v1alpha1.ExecuteOptimisticBlockStreamRequest") } - fn visit_map(self, mut map_: V) -> std::result::Result + fn visit_map(self, mut map_: V) -> std::result::Result where V: serde::de::MapAccess<'de>, { - while map_.next_key::()?.is_some() { - let _ = map_.next_value::()?; + let mut base_block__ = None; + while let Some(k) = map_.next_key()? { + match k { + GeneratedField::BaseBlock => { + if base_block__.is_some() { + return Err(serde::de::Error::duplicate_field("baseBlock")); + } + base_block__ = map_.next_value()?; + } + } } - Ok(StreamBundlesRequest { + Ok(ExecuteOptimisticBlockStreamRequest { + base_block: base_block__, }) } } - deserializer.deserialize_struct("astria.bundle.v1alpha1.StreamBundlesRequest", FIELDS, GeneratedVisitor) + deserializer.deserialize_struct("astria.bundle.v1alpha1.ExecuteOptimisticBlockStreamRequest", FIELDS, GeneratedVisitor) } } -impl serde::Serialize for StreamExecuteOptimisticBlockRequest { +impl serde::Serialize for ExecuteOptimisticBlockStreamResponse { #[allow(deprecated)] fn serialize(&self, serializer: S) -> std::result::Result where @@ -365,14 +386,21 @@ impl serde::Serialize for StreamExecuteOptimisticBlockRequest { if self.block.is_some() { len += 1; } - let mut struct_ser = serializer.serialize_struct("astria.bundle.v1alpha1.StreamExecuteOptimisticBlockRequest", len)?; + if !self.base_sequencer_block_hash.is_empty() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("astria.bundle.v1alpha1.ExecuteOptimisticBlockStreamResponse", len)?; if let Some(v) = self.block.as_ref() { struct_ser.serialize_field("block", v)?; } + if !self.base_sequencer_block_hash.is_empty() { + #[allow(clippy::needless_borrow)] + struct_ser.serialize_field("baseSequencerBlockHash", pbjson::private::base64::encode(&self.base_sequencer_block_hash).as_str())?; + } struct_ser.end() } } -impl<'de> serde::Deserialize<'de> for StreamExecuteOptimisticBlockRequest { +impl<'de> serde::Deserialize<'de> for ExecuteOptimisticBlockStreamResponse { #[allow(deprecated)] fn deserialize(deserializer: D) -> std::result::Result where @@ -380,11 +408,14 @@ impl<'de> serde::Deserialize<'de> for StreamExecuteOptimisticBlockRequest { { const FIELDS: &[&str] = &[ "block", + "base_sequencer_block_hash", + "baseSequencerBlockHash", ]; #[allow(clippy::enum_variant_names)] enum GeneratedField { Block, + BaseSequencerBlockHash, } impl<'de> serde::Deserialize<'de> for GeneratedField { fn deserialize(deserializer: D) -> std::result::Result @@ -407,6 +438,7 @@ impl<'de> serde::Deserialize<'de> for StreamExecuteOptimisticBlockRequest { { match value { "block" => Ok(GeneratedField::Block), + "baseSequencerBlockHash" | "base_sequencer_block_hash" => Ok(GeneratedField::BaseSequencerBlockHash), _ => Err(serde::de::Error::unknown_field(value, FIELDS)), } } @@ -416,17 +448,18 @@ impl<'de> serde::Deserialize<'de> for StreamExecuteOptimisticBlockRequest { } struct GeneratedVisitor; impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { - type Value = StreamExecuteOptimisticBlockRequest; + type Value = ExecuteOptimisticBlockStreamResponse; fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - formatter.write_str("struct astria.bundle.v1alpha1.StreamExecuteOptimisticBlockRequest") + formatter.write_str("struct astria.bundle.v1alpha1.ExecuteOptimisticBlockStreamResponse") } - fn visit_map(self, mut map_: V) -> std::result::Result + fn visit_map(self, mut map_: V) -> std::result::Result where V: serde::de::MapAccess<'de>, { let mut block__ = None; + let mut base_sequencer_block_hash__ = None; while let Some(k) = map_.next_key()? { match k { GeneratedField::Block => { @@ -435,57 +468,127 @@ impl<'de> serde::Deserialize<'de> for StreamExecuteOptimisticBlockRequest { } block__ = map_.next_value()?; } + GeneratedField::BaseSequencerBlockHash => { + if base_sequencer_block_hash__.is_some() { + return Err(serde::de::Error::duplicate_field("baseSequencerBlockHash")); + } + base_sequencer_block_hash__ = + Some(map_.next_value::<::pbjson::private::BytesDeserialize<_>>()?.0) + ; + } } } - Ok(StreamExecuteOptimisticBlockRequest { + Ok(ExecuteOptimisticBlockStreamResponse { block: block__, + base_sequencer_block_hash: base_sequencer_block_hash__.unwrap_or_default(), }) } } - deserializer.deserialize_struct("astria.bundle.v1alpha1.StreamExecuteOptimisticBlockRequest", FIELDS, GeneratedVisitor) + deserializer.deserialize_struct("astria.bundle.v1alpha1.ExecuteOptimisticBlockStreamResponse", FIELDS, GeneratedVisitor) } } -impl serde::Serialize for StreamExecuteOptimisticBlockResponse { +impl serde::Serialize for GetBundleStreamRequest { #[allow(deprecated)] fn serialize(&self, serializer: S) -> std::result::Result where S: serde::Serializer, { use serde::ser::SerializeStruct; - let mut len = 0; - if self.block.is_some() { - len += 1; + let len = 0; + let struct_ser = serializer.serialize_struct("astria.bundle.v1alpha1.GetBundleStreamRequest", len)?; + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for GetBundleStreamRequest { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { } - if !self.base_sequencer_block_hash.is_empty() { - len += 1; + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + Err(serde::de::Error::unknown_field(value, FIELDS)) + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } } - let mut struct_ser = serializer.serialize_struct("astria.bundle.v1alpha1.StreamExecuteOptimisticBlockResponse", len)?; - if let Some(v) = self.block.as_ref() { - struct_ser.serialize_field("block", v)?; + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GetBundleStreamRequest; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct astria.bundle.v1alpha1.GetBundleStreamRequest") + } + + fn visit_map(self, mut map_: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + while map_.next_key::()?.is_some() { + let _ = map_.next_value::()?; + } + Ok(GetBundleStreamRequest { + }) + } } - if !self.base_sequencer_block_hash.is_empty() { - #[allow(clippy::needless_borrow)] - struct_ser.serialize_field("baseSequencerBlockHash", pbjson::private::base64::encode(&self.base_sequencer_block_hash).as_str())?; + deserializer.deserialize_struct("astria.bundle.v1alpha1.GetBundleStreamRequest", FIELDS, GeneratedVisitor) + } +} +impl serde::Serialize for GetBundleStreamResponse { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if self.bundle.is_some() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("astria.bundle.v1alpha1.GetBundleStreamResponse", len)?; + if let Some(v) = self.bundle.as_ref() { + struct_ser.serialize_field("bundle", v)?; } struct_ser.end() } } -impl<'de> serde::Deserialize<'de> for StreamExecuteOptimisticBlockResponse { +impl<'de> serde::Deserialize<'de> for GetBundleStreamResponse { #[allow(deprecated)] fn deserialize(deserializer: D) -> std::result::Result where D: serde::Deserializer<'de>, { const FIELDS: &[&str] = &[ - "block", - "base_sequencer_block_hash", - "baseSequencerBlockHash", + "bundle", ]; #[allow(clippy::enum_variant_names)] enum GeneratedField { - Block, - BaseSequencerBlockHash, + Bundle, } impl<'de> serde::Deserialize<'de> for GeneratedField { fn deserialize(deserializer: D) -> std::result::Result @@ -507,8 +610,7 @@ impl<'de> serde::Deserialize<'de> for StreamExecuteOptimisticBlockResponse { E: serde::de::Error, { match value { - "block" => Ok(GeneratedField::Block), - "baseSequencerBlockHash" | "base_sequencer_block_hash" => Ok(GeneratedField::BaseSequencerBlockHash), + "bundle" => Ok(GeneratedField::Bundle), _ => Err(serde::de::Error::unknown_field(value, FIELDS)), } } @@ -518,42 +620,32 @@ impl<'de> serde::Deserialize<'de> for StreamExecuteOptimisticBlockResponse { } struct GeneratedVisitor; impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { - type Value = StreamExecuteOptimisticBlockResponse; + type Value = GetBundleStreamResponse; fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - formatter.write_str("struct astria.bundle.v1alpha1.StreamExecuteOptimisticBlockResponse") + formatter.write_str("struct astria.bundle.v1alpha1.GetBundleStreamResponse") } - fn visit_map(self, mut map_: V) -> std::result::Result + fn visit_map(self, mut map_: V) -> std::result::Result where V: serde::de::MapAccess<'de>, { - let mut block__ = None; - let mut base_sequencer_block_hash__ = None; + let mut bundle__ = None; while let Some(k) = map_.next_key()? { match k { - GeneratedField::Block => { - if block__.is_some() { - return Err(serde::de::Error::duplicate_field("block")); - } - block__ = map_.next_value()?; - } - GeneratedField::BaseSequencerBlockHash => { - if base_sequencer_block_hash__.is_some() { - return Err(serde::de::Error::duplicate_field("baseSequencerBlockHash")); + GeneratedField::Bundle => { + if bundle__.is_some() { + return Err(serde::de::Error::duplicate_field("bundle")); } - base_sequencer_block_hash__ = - Some(map_.next_value::<::pbjson::private::BytesDeserialize<_>>()?.0) - ; + bundle__ = map_.next_value()?; } } } - Ok(StreamExecuteOptimisticBlockResponse { - block: block__, - base_sequencer_block_hash: base_sequencer_block_hash__.unwrap_or_default(), + Ok(GetBundleStreamResponse { + bundle: bundle__, }) } } - deserializer.deserialize_struct("astria.bundle.v1alpha1.StreamExecuteOptimisticBlockResponse", FIELDS, GeneratedVisitor) + deserializer.deserialize_struct("astria.bundle.v1alpha1.GetBundleStreamResponse", FIELDS, GeneratedVisitor) } } diff --git a/crates/astria-core/src/generated/astria.sequencerblock.v1alpha1.rs b/crates/astria-core/src/generated/astria.sequencerblock.v1alpha1.rs index 4c42a1cb95..8d392843df 100644 --- a/crates/astria-core/src/generated/astria.sequencerblock.v1alpha1.rs +++ b/crates/astria-core/src/generated/astria.sequencerblock.v1alpha1.rs @@ -330,9 +330,9 @@ impl ::prost::Name for SubmittedMetadata { } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] -pub struct StreamBlockCommitmentsRequest {} -impl ::prost::Name for StreamBlockCommitmentsRequest { - const NAME: &'static str = "StreamBlockCommitmentsRequest"; +pub struct GetBlockCommitmentStreamRequest {} +impl ::prost::Name for GetBlockCommitmentStreamRequest { + const NAME: &'static str = "GetBlockCommitmentStreamRequest"; const PACKAGE: &'static str = "astria.sequencerblock.v1alpha1"; fn full_name() -> ::prost::alloc::string::String { ::prost::alloc::format!("astria.sequencerblock.v1alpha1.{}", Self::NAME) @@ -358,13 +358,26 @@ impl ::prost::Name for SequencerBlockCommit { } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] -pub struct StreamOptimisticBlockRequest { +pub struct GetBlockCommitmentStreamResponse { + #[prost(message, optional, tag = "1")] + pub commitment: ::core::option::Option, +} +impl ::prost::Name for GetBlockCommitmentStreamResponse { + const NAME: &'static str = "GetBlockCommitmentStreamResponse"; + const PACKAGE: &'static str = "astria.sequencerblock.v1alpha1"; + fn full_name() -> ::prost::alloc::string::String { + ::prost::alloc::format!("astria.sequencerblock.v1alpha1.{}", Self::NAME) + } +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetOptimisticBlockStreamRequest { /// The rollup id for which the Sequencer block is being streamed. #[prost(message, optional, tag = "1")] pub rollup_id: ::core::option::Option, } -impl ::prost::Name for StreamOptimisticBlockRequest { - const NAME: &'static str = "StreamOptimisticBlockRequest"; +impl ::prost::Name for GetOptimisticBlockStreamRequest { + const NAME: &'static str = "GetOptimisticBlockStreamRequest"; const PACKAGE: &'static str = "astria.sequencerblock.v1alpha1"; fn full_name() -> ::prost::alloc::string::String { ::prost::alloc::format!("astria.sequencerblock.v1alpha1.{}", Self::NAME) @@ -372,13 +385,13 @@ impl ::prost::Name for StreamOptimisticBlockRequest { } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] -pub struct StreamOptimisticBlockResponse { +pub struct GetOptimisticBlockStreamResponse { /// The optimistic Sequencer block that is being streamed, filtered for the provided rollup id. #[prost(message, optional, tag = "1")] pub block: ::core::option::Option, } -impl ::prost::Name for StreamOptimisticBlockResponse { - const NAME: &'static str = "StreamOptimisticBlockResponse"; +impl ::prost::Name for GetOptimisticBlockStreamResponse { + const NAME: &'static str = "GetOptimisticBlockStreamResponse"; const PACKAGE: &'static str = "astria.sequencerblock.v1alpha1"; fn full_name() -> ::prost::alloc::string::String { ::prost::alloc::format!("astria.sequencerblock.v1alpha1.{}", Self::NAME) @@ -475,12 +488,12 @@ pub mod optimistic_block_service_client { } /// The Sequencer will stream the optimistic Sequencer block (filtered for the provided /// rollup id) to the Auctioneer. - pub async fn stream_optimistic_block( + pub async fn get_optimistic_block_stream( &mut self, - request: impl tonic::IntoRequest, + request: impl tonic::IntoRequest, ) -> std::result::Result< tonic::Response< - tonic::codec::Streaming, + tonic::codec::Streaming, >, tonic::Status, > { @@ -495,24 +508,26 @@ pub mod optimistic_block_service_client { })?; let codec = tonic::codec::ProstCodec::default(); let path = http::uri::PathAndQuery::from_static( - "/astria.sequencerblock.v1alpha1.OptimisticBlockService/StreamOptimisticBlock", + "/astria.sequencerblock.v1alpha1.OptimisticBlockService/GetOptimisticBlockStream", ); let mut req = request.into_request(); req.extensions_mut() .insert( GrpcMethod::new( "astria.sequencerblock.v1alpha1.OptimisticBlockService", - "StreamOptimisticBlock", + "GetOptimisticBlockStream", ), ); self.inner.server_streaming(req, path, codec).await } /// The Sequencer will stream the block commits to the Auctioneer. - pub async fn stream_block_commitments( + pub async fn get_block_commitment_stream( &mut self, - request: impl tonic::IntoRequest, + request: impl tonic::IntoRequest, ) -> std::result::Result< - tonic::Response>, + tonic::Response< + tonic::codec::Streaming, + >, tonic::Status, > { self.inner @@ -526,14 +541,14 @@ pub mod optimistic_block_service_client { })?; let codec = tonic::codec::ProstCodec::default(); let path = http::uri::PathAndQuery::from_static( - "/astria.sequencerblock.v1alpha1.OptimisticBlockService/StreamBlockCommitments", + "/astria.sequencerblock.v1alpha1.OptimisticBlockService/GetBlockCommitmentStream", ); let mut req = request.into_request(); req.extensions_mut() .insert( GrpcMethod::new( "astria.sequencerblock.v1alpha1.OptimisticBlockService", - "StreamBlockCommitments", + "GetBlockCommitmentStream", ), ); self.inner.server_streaming(req, path, codec).await @@ -548,10 +563,10 @@ pub mod optimistic_block_service_server { /// Generated trait containing gRPC methods that should be implemented for use with OptimisticBlockServiceServer. #[async_trait] pub trait OptimisticBlockService: Send + Sync + 'static { - /// Server streaming response type for the StreamOptimisticBlock method. - type StreamOptimisticBlockStream: tonic::codegen::tokio_stream::Stream< + /// Server streaming response type for the GetOptimisticBlockStream method. + type GetOptimisticBlockStreamStream: tonic::codegen::tokio_stream::Stream< Item = std::result::Result< - super::StreamOptimisticBlockResponse, + super::GetOptimisticBlockStreamResponse, tonic::Status, >, > @@ -559,25 +574,28 @@ pub mod optimistic_block_service_server { + 'static; /// The Sequencer will stream the optimistic Sequencer block (filtered for the provided /// rollup id) to the Auctioneer. - async fn stream_optimistic_block( + async fn get_optimistic_block_stream( self: std::sync::Arc, - request: tonic::Request, + request: tonic::Request, ) -> std::result::Result< - tonic::Response, + tonic::Response, tonic::Status, >; - /// Server streaming response type for the StreamBlockCommitments method. - type StreamBlockCommitmentsStream: tonic::codegen::tokio_stream::Stream< - Item = std::result::Result, + /// Server streaming response type for the GetBlockCommitmentStream method. + type GetBlockCommitmentStreamStream: tonic::codegen::tokio_stream::Stream< + Item = std::result::Result< + super::GetBlockCommitmentStreamResponse, + tonic::Status, + >, > + Send + 'static; /// The Sequencer will stream the block commits to the Auctioneer. - async fn stream_block_commitments( + async fn get_block_commitment_stream( self: std::sync::Arc, - request: tonic::Request, + request: tonic::Request, ) -> std::result::Result< - tonic::Response, + tonic::Response, tonic::Status, >; } @@ -662,29 +680,31 @@ pub mod optimistic_block_service_server { fn call(&mut self, req: http::Request) -> Self::Future { let inner = self.inner.clone(); match req.uri().path() { - "/astria.sequencerblock.v1alpha1.OptimisticBlockService/StreamOptimisticBlock" => { + "/astria.sequencerblock.v1alpha1.OptimisticBlockService/GetOptimisticBlockStream" => { #[allow(non_camel_case_types)] - struct StreamOptimisticBlockSvc( + struct GetOptimisticBlockStreamSvc( pub Arc, ); impl< T: OptimisticBlockService, > tonic::server::ServerStreamingService< - super::StreamOptimisticBlockRequest, - > for StreamOptimisticBlockSvc { - type Response = super::StreamOptimisticBlockResponse; - type ResponseStream = T::StreamOptimisticBlockStream; + super::GetOptimisticBlockStreamRequest, + > for GetOptimisticBlockStreamSvc { + type Response = super::GetOptimisticBlockStreamResponse; + type ResponseStream = T::GetOptimisticBlockStreamStream; type Future = BoxFuture< tonic::Response, tonic::Status, >; fn call( &mut self, - request: tonic::Request, + request: tonic::Request< + super::GetOptimisticBlockStreamRequest, + >, ) -> Self::Future { let inner = Arc::clone(&self.0); let fut = async move { - ::stream_optimistic_block( + ::get_optimistic_block_stream( inner, request, ) @@ -700,7 +720,7 @@ pub mod optimistic_block_service_server { let inner = self.inner.clone(); let fut = async move { let inner = inner.0; - let method = StreamOptimisticBlockSvc(inner); + let method = GetOptimisticBlockStreamSvc(inner); let codec = tonic::codec::ProstCodec::default(); let mut grpc = tonic::server::Grpc::new(codec) .apply_compression_config( @@ -716,29 +736,31 @@ pub mod optimistic_block_service_server { }; Box::pin(fut) } - "/astria.sequencerblock.v1alpha1.OptimisticBlockService/StreamBlockCommitments" => { + "/astria.sequencerblock.v1alpha1.OptimisticBlockService/GetBlockCommitmentStream" => { #[allow(non_camel_case_types)] - struct StreamBlockCommitmentsSvc( + struct GetBlockCommitmentStreamSvc( pub Arc, ); impl< T: OptimisticBlockService, > tonic::server::ServerStreamingService< - super::StreamBlockCommitmentsRequest, - > for StreamBlockCommitmentsSvc { - type Response = super::SequencerBlockCommit; - type ResponseStream = T::StreamBlockCommitmentsStream; + super::GetBlockCommitmentStreamRequest, + > for GetBlockCommitmentStreamSvc { + type Response = super::GetBlockCommitmentStreamResponse; + type ResponseStream = T::GetBlockCommitmentStreamStream; type Future = BoxFuture< tonic::Response, tonic::Status, >; fn call( &mut self, - request: tonic::Request, + request: tonic::Request< + super::GetBlockCommitmentStreamRequest, + >, ) -> Self::Future { let inner = Arc::clone(&self.0); let fut = async move { - ::stream_block_commitments( + ::get_block_commitment_stream( inner, request, ) @@ -754,7 +776,7 @@ pub mod optimistic_block_service_server { let inner = self.inner.clone(); let fut = async move { let inner = inner.0; - let method = StreamBlockCommitmentsSvc(inner); + let method = GetBlockCommitmentStreamSvc(inner); let codec = tonic::codec::ProstCodec::default(); let mut grpc = tonic::server::Grpc::new(codec) .apply_compression_config( diff --git a/crates/astria-core/src/generated/astria.sequencerblock.v1alpha1.serde.rs b/crates/astria-core/src/generated/astria.sequencerblock.v1alpha1.serde.rs index c0c74674c7..dbb14458d2 100644 --- a/crates/astria-core/src/generated/astria.sequencerblock.v1alpha1.serde.rs +++ b/crates/astria-core/src/generated/astria.sequencerblock.v1alpha1.serde.rs @@ -386,6 +386,168 @@ impl<'de> serde::Deserialize<'de> for FilteredSequencerBlock { deserializer.deserialize_struct("astria.sequencerblock.v1alpha1.FilteredSequencerBlock", FIELDS, GeneratedVisitor) } } +impl serde::Serialize for GetBlockCommitmentStreamRequest { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let len = 0; + let struct_ser = serializer.serialize_struct("astria.sequencerblock.v1alpha1.GetBlockCommitmentStreamRequest", len)?; + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for GetBlockCommitmentStreamRequest { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + Err(serde::de::Error::unknown_field(value, FIELDS)) + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GetBlockCommitmentStreamRequest; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct astria.sequencerblock.v1alpha1.GetBlockCommitmentStreamRequest") + } + + fn visit_map(self, mut map_: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + while map_.next_key::()?.is_some() { + let _ = map_.next_value::()?; + } + Ok(GetBlockCommitmentStreamRequest { + }) + } + } + deserializer.deserialize_struct("astria.sequencerblock.v1alpha1.GetBlockCommitmentStreamRequest", FIELDS, GeneratedVisitor) + } +} +impl serde::Serialize for GetBlockCommitmentStreamResponse { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if self.commitment.is_some() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("astria.sequencerblock.v1alpha1.GetBlockCommitmentStreamResponse", len)?; + if let Some(v) = self.commitment.as_ref() { + struct_ser.serialize_field("commitment", v)?; + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for GetBlockCommitmentStreamResponse { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "commitment", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + Commitment, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "commitment" => Ok(GeneratedField::Commitment), + _ => Err(serde::de::Error::unknown_field(value, FIELDS)), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GetBlockCommitmentStreamResponse; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct astria.sequencerblock.v1alpha1.GetBlockCommitmentStreamResponse") + } + + fn visit_map(self, mut map_: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut commitment__ = None; + while let Some(k) = map_.next_key()? { + match k { + GeneratedField::Commitment => { + if commitment__.is_some() { + return Err(serde::de::Error::duplicate_field("commitment")); + } + commitment__ = map_.next_value()?; + } + } + } + Ok(GetBlockCommitmentStreamResponse { + commitment: commitment__, + }) + } + } + deserializer.deserialize_struct("astria.sequencerblock.v1alpha1.GetBlockCommitmentStreamResponse", FIELDS, GeneratedVisitor) + } +} impl serde::Serialize for GetFilteredSequencerBlockRequest { #[allow(deprecated)] fn serialize(&self, serializer: S) -> std::result::Result @@ -462,40 +624,223 @@ impl<'de> serde::Deserialize<'de> for GetFilteredSequencerBlockRequest { type Value = GetFilteredSequencerBlockRequest; fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - formatter.write_str("struct astria.sequencerblock.v1alpha1.GetFilteredSequencerBlockRequest") + formatter.write_str("struct astria.sequencerblock.v1alpha1.GetFilteredSequencerBlockRequest") + } + + fn visit_map(self, mut map_: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut height__ = None; + let mut rollup_ids__ = None; + while let Some(k) = map_.next_key()? { + match k { + GeneratedField::Height => { + if height__.is_some() { + return Err(serde::de::Error::duplicate_field("height")); + } + height__ = + Some(map_.next_value::<::pbjson::private::NumberDeserialize<_>>()?.0) + ; + } + GeneratedField::RollupIds => { + if rollup_ids__.is_some() { + return Err(serde::de::Error::duplicate_field("rollupIds")); + } + rollup_ids__ = Some(map_.next_value()?); + } + } + } + Ok(GetFilteredSequencerBlockRequest { + height: height__.unwrap_or_default(), + rollup_ids: rollup_ids__.unwrap_or_default(), + }) + } + } + deserializer.deserialize_struct("astria.sequencerblock.v1alpha1.GetFilteredSequencerBlockRequest", FIELDS, GeneratedVisitor) + } +} +impl serde::Serialize for GetOptimisticBlockStreamRequest { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if self.rollup_id.is_some() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("astria.sequencerblock.v1alpha1.GetOptimisticBlockStreamRequest", len)?; + if let Some(v) = self.rollup_id.as_ref() { + struct_ser.serialize_field("rollupId", v)?; + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for GetOptimisticBlockStreamRequest { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "rollup_id", + "rollupId", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + RollupId, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "rollupId" | "rollup_id" => Ok(GeneratedField::RollupId), + _ => Err(serde::de::Error::unknown_field(value, FIELDS)), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GetOptimisticBlockStreamRequest; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct astria.sequencerblock.v1alpha1.GetOptimisticBlockStreamRequest") + } + + fn visit_map(self, mut map_: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut rollup_id__ = None; + while let Some(k) = map_.next_key()? { + match k { + GeneratedField::RollupId => { + if rollup_id__.is_some() { + return Err(serde::de::Error::duplicate_field("rollupId")); + } + rollup_id__ = map_.next_value()?; + } + } + } + Ok(GetOptimisticBlockStreamRequest { + rollup_id: rollup_id__, + }) + } + } + deserializer.deserialize_struct("astria.sequencerblock.v1alpha1.GetOptimisticBlockStreamRequest", FIELDS, GeneratedVisitor) + } +} +impl serde::Serialize for GetOptimisticBlockStreamResponse { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if self.block.is_some() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("astria.sequencerblock.v1alpha1.GetOptimisticBlockStreamResponse", len)?; + if let Some(v) = self.block.as_ref() { + struct_ser.serialize_field("block", v)?; + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for GetOptimisticBlockStreamResponse { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "block", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + Block, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "block" => Ok(GeneratedField::Block), + _ => Err(serde::de::Error::unknown_field(value, FIELDS)), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GetOptimisticBlockStreamResponse; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct astria.sequencerblock.v1alpha1.GetOptimisticBlockStreamResponse") } - fn visit_map(self, mut map_: V) -> std::result::Result + fn visit_map(self, mut map_: V) -> std::result::Result where V: serde::de::MapAccess<'de>, { - let mut height__ = None; - let mut rollup_ids__ = None; + let mut block__ = None; while let Some(k) = map_.next_key()? { match k { - GeneratedField::Height => { - if height__.is_some() { - return Err(serde::de::Error::duplicate_field("height")); - } - height__ = - Some(map_.next_value::<::pbjson::private::NumberDeserialize<_>>()?.0) - ; - } - GeneratedField::RollupIds => { - if rollup_ids__.is_some() { - return Err(serde::de::Error::duplicate_field("rollupIds")); + GeneratedField::Block => { + if block__.is_some() { + return Err(serde::de::Error::duplicate_field("block")); } - rollup_ids__ = Some(map_.next_value()?); + block__ = map_.next_value()?; } } } - Ok(GetFilteredSequencerBlockRequest { - height: height__.unwrap_or_default(), - rollup_ids: rollup_ids__.unwrap_or_default(), + Ok(GetOptimisticBlockStreamResponse { + block: block__, }) } } - deserializer.deserialize_struct("astria.sequencerblock.v1alpha1.GetFilteredSequencerBlockRequest", FIELDS, GeneratedVisitor) + deserializer.deserialize_struct("astria.sequencerblock.v1alpha1.GetOptimisticBlockStreamResponse", FIELDS, GeneratedVisitor) } } impl serde::Serialize for GetPendingNonceRequest { @@ -1488,260 +1833,6 @@ impl<'de> serde::Deserialize<'de> for SequencerBlockHeader { deserializer.deserialize_struct("astria.sequencerblock.v1alpha1.SequencerBlockHeader", FIELDS, GeneratedVisitor) } } -impl serde::Serialize for StreamBlockCommitmentsRequest { - #[allow(deprecated)] - fn serialize(&self, serializer: S) -> std::result::Result - where - S: serde::Serializer, - { - use serde::ser::SerializeStruct; - let len = 0; - let struct_ser = serializer.serialize_struct("astria.sequencerblock.v1alpha1.StreamBlockCommitmentsRequest", len)?; - struct_ser.end() - } -} -impl<'de> serde::Deserialize<'de> for StreamBlockCommitmentsRequest { - #[allow(deprecated)] - fn deserialize(deserializer: D) -> std::result::Result - where - D: serde::Deserializer<'de>, - { - const FIELDS: &[&str] = &[ - ]; - - #[allow(clippy::enum_variant_names)] - enum GeneratedField { - } - impl<'de> serde::Deserialize<'de> for GeneratedField { - fn deserialize(deserializer: D) -> std::result::Result - where - D: serde::Deserializer<'de>, - { - struct GeneratedVisitor; - - impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { - type Value = GeneratedField; - - fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(formatter, "expected one of: {:?}", &FIELDS) - } - - #[allow(unused_variables)] - fn visit_str(self, value: &str) -> std::result::Result - where - E: serde::de::Error, - { - Err(serde::de::Error::unknown_field(value, FIELDS)) - } - } - deserializer.deserialize_identifier(GeneratedVisitor) - } - } - struct GeneratedVisitor; - impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { - type Value = StreamBlockCommitmentsRequest; - - fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - formatter.write_str("struct astria.sequencerblock.v1alpha1.StreamBlockCommitmentsRequest") - } - - fn visit_map(self, mut map_: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, - { - while map_.next_key::()?.is_some() { - let _ = map_.next_value::()?; - } - Ok(StreamBlockCommitmentsRequest { - }) - } - } - deserializer.deserialize_struct("astria.sequencerblock.v1alpha1.StreamBlockCommitmentsRequest", FIELDS, GeneratedVisitor) - } -} -impl serde::Serialize for StreamOptimisticBlockRequest { - #[allow(deprecated)] - fn serialize(&self, serializer: S) -> std::result::Result - where - S: serde::Serializer, - { - use serde::ser::SerializeStruct; - let mut len = 0; - if self.rollup_id.is_some() { - len += 1; - } - let mut struct_ser = serializer.serialize_struct("astria.sequencerblock.v1alpha1.StreamOptimisticBlockRequest", len)?; - if let Some(v) = self.rollup_id.as_ref() { - struct_ser.serialize_field("rollupId", v)?; - } - struct_ser.end() - } -} -impl<'de> serde::Deserialize<'de> for StreamOptimisticBlockRequest { - #[allow(deprecated)] - fn deserialize(deserializer: D) -> std::result::Result - where - D: serde::Deserializer<'de>, - { - const FIELDS: &[&str] = &[ - "rollup_id", - "rollupId", - ]; - - #[allow(clippy::enum_variant_names)] - enum GeneratedField { - RollupId, - } - impl<'de> serde::Deserialize<'de> for GeneratedField { - fn deserialize(deserializer: D) -> std::result::Result - where - D: serde::Deserializer<'de>, - { - struct GeneratedVisitor; - - impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { - type Value = GeneratedField; - - fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(formatter, "expected one of: {:?}", &FIELDS) - } - - #[allow(unused_variables)] - fn visit_str(self, value: &str) -> std::result::Result - where - E: serde::de::Error, - { - match value { - "rollupId" | "rollup_id" => Ok(GeneratedField::RollupId), - _ => Err(serde::de::Error::unknown_field(value, FIELDS)), - } - } - } - deserializer.deserialize_identifier(GeneratedVisitor) - } - } - struct GeneratedVisitor; - impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { - type Value = StreamOptimisticBlockRequest; - - fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - formatter.write_str("struct astria.sequencerblock.v1alpha1.StreamOptimisticBlockRequest") - } - - fn visit_map(self, mut map_: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, - { - let mut rollup_id__ = None; - while let Some(k) = map_.next_key()? { - match k { - GeneratedField::RollupId => { - if rollup_id__.is_some() { - return Err(serde::de::Error::duplicate_field("rollupId")); - } - rollup_id__ = map_.next_value()?; - } - } - } - Ok(StreamOptimisticBlockRequest { - rollup_id: rollup_id__, - }) - } - } - deserializer.deserialize_struct("astria.sequencerblock.v1alpha1.StreamOptimisticBlockRequest", FIELDS, GeneratedVisitor) - } -} -impl serde::Serialize for StreamOptimisticBlockResponse { - #[allow(deprecated)] - fn serialize(&self, serializer: S) -> std::result::Result - where - S: serde::Serializer, - { - use serde::ser::SerializeStruct; - let mut len = 0; - if self.block.is_some() { - len += 1; - } - let mut struct_ser = serializer.serialize_struct("astria.sequencerblock.v1alpha1.StreamOptimisticBlockResponse", len)?; - if let Some(v) = self.block.as_ref() { - struct_ser.serialize_field("block", v)?; - } - struct_ser.end() - } -} -impl<'de> serde::Deserialize<'de> for StreamOptimisticBlockResponse { - #[allow(deprecated)] - fn deserialize(deserializer: D) -> std::result::Result - where - D: serde::Deserializer<'de>, - { - const FIELDS: &[&str] = &[ - "block", - ]; - - #[allow(clippy::enum_variant_names)] - enum GeneratedField { - Block, - } - impl<'de> serde::Deserialize<'de> for GeneratedField { - fn deserialize(deserializer: D) -> std::result::Result - where - D: serde::Deserializer<'de>, - { - struct GeneratedVisitor; - - impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { - type Value = GeneratedField; - - fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(formatter, "expected one of: {:?}", &FIELDS) - } - - #[allow(unused_variables)] - fn visit_str(self, value: &str) -> std::result::Result - where - E: serde::de::Error, - { - match value { - "block" => Ok(GeneratedField::Block), - _ => Err(serde::de::Error::unknown_field(value, FIELDS)), - } - } - } - deserializer.deserialize_identifier(GeneratedVisitor) - } - } - struct GeneratedVisitor; - impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { - type Value = StreamOptimisticBlockResponse; - - fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - formatter.write_str("struct astria.sequencerblock.v1alpha1.StreamOptimisticBlockResponse") - } - - fn visit_map(self, mut map_: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, - { - let mut block__ = None; - while let Some(k) = map_.next_key()? { - match k { - GeneratedField::Block => { - if block__.is_some() { - return Err(serde::de::Error::duplicate_field("block")); - } - block__ = map_.next_value()?; - } - } - } - Ok(StreamOptimisticBlockResponse { - block: block__, - }) - } - } - deserializer.deserialize_struct("astria.sequencerblock.v1alpha1.StreamOptimisticBlockResponse", FIELDS, GeneratedVisitor) - } -} impl serde::Serialize for SubmittedMetadata { #[allow(deprecated)] fn serialize(&self, serializer: S) -> std::result::Result diff --git a/proto/executionapis/astria/bundle/v1alpha1/bundle.proto b/proto/executionapis/astria/bundle/v1alpha1/bundle.proto index c077f28a0e..beb5718de4 100644 --- a/proto/executionapis/astria/bundle/v1alpha1/bundle.proto +++ b/proto/executionapis/astria/bundle/v1alpha1/bundle.proto @@ -17,11 +17,11 @@ message BaseBlock { google.protobuf.Timestamp timestamp = 3; } -message StreamExecuteOptimisticBlockRequest { - BaseBlock block = 1; +message ExecuteOptimisticBlockStreamRequest { + BaseBlock base_block = 1; } -message StreamExecuteOptimisticBlockResponse { +message ExecuteOptimisticBlockStreamResponse { // Metadata identifying the block resulting from executing a block. Includes number, hash, // parent hash and timestamp. astria.execution.v1alpha2.Block block = 1; @@ -31,7 +31,7 @@ message StreamExecuteOptimisticBlockResponse { bytes base_sequencer_block_hash = 2; } -message StreamBundlesRequest {} +message GetBundleStreamRequest {} // Information for the bundle submitter to know how to submit the bundle. // The fee and base_sequencer_block_hash are not necessarily strictly necessary @@ -53,15 +53,19 @@ message Bundle { bytes prev_rollup_block_hash = 4; } +message GetBundleStreamResponse { + Bundle bundle = 1; +} + service OptimisticExecutionService { // Stream blocks from the Auctioneer to Geth for optimistic execution. Geth will stream back // metadata from the executed blocks. - rpc StreamExecuteOptimisticBlock(stream StreamExecuteOptimisticBlockRequest) returns (stream StreamExecuteOptimisticBlockResponse); + rpc ExecuteOptimisticBlockStream(stream ExecuteOptimisticBlockStreamRequest) returns (stream ExecuteOptimisticBlockStreamResponse); } service BundleService { // A bundle submitter requests bundles given a new optimistic Sequencer block, // and receives a stream of potential bundles for submission, until either a timeout // or the connection is closed by the client. - rpc StreamBundles(StreamBundlesRequest) returns (stream Bundle); + rpc GetBundleStream(GetBundleStreamRequest) returns (stream GetBundleStreamResponse); } diff --git a/proto/sequencerblockapis/astria/sequencerblock/v1alpha1/optimistic_block.proto b/proto/sequencerblockapis/astria/sequencerblock/v1alpha1/optimistic_block.proto index 02c4ae0c35..575643e73b 100644 --- a/proto/sequencerblockapis/astria/sequencerblock/v1alpha1/optimistic_block.proto +++ b/proto/sequencerblockapis/astria/sequencerblock/v1alpha1/optimistic_block.proto @@ -5,7 +5,7 @@ package astria.sequencerblock.v1alpha1; import "astria/primitive/v1/types.proto"; import "astria/sequencerblock/v1alpha1/block.proto"; -message StreamBlockCommitmentsRequest {} +message GetBlockCommitmentStreamRequest {} // Identifying metadata for blocks that have been successfully committed in the Sequencer. message SequencerBlockCommit { @@ -15,12 +15,16 @@ message SequencerBlockCommit { bytes block_hash = 2; } -message StreamOptimisticBlockRequest { +message GetBlockCommitmentStreamResponse { + SequencerBlockCommit commitment = 1; +} + +message GetOptimisticBlockStreamRequest { // The rollup id for which the Sequencer block is being streamed. astria.primitive.v1.RollupId rollup_id = 1; } -message StreamOptimisticBlockResponse { +message GetOptimisticBlockStreamResponse { // The optimistic Sequencer block that is being streamed, filtered for the provided rollup id. astria.sequencerblock.v1alpha1.FilteredSequencerBlock block = 1; } @@ -29,7 +33,7 @@ message StreamOptimisticBlockResponse { service OptimisticBlockService { // The Sequencer will stream the optimistic Sequencer block (filtered for the provided // rollup id) to the Auctioneer. - rpc StreamOptimisticBlock(StreamOptimisticBlockRequest) returns (stream StreamOptimisticBlockResponse); + rpc GetOptimisticBlockStream(GetOptimisticBlockStreamRequest) returns (stream GetOptimisticBlockStreamResponse); // The Sequencer will stream the block commits to the Auctioneer. - rpc StreamBlockCommitments(StreamBlockCommitmentsRequest) returns (stream SequencerBlockCommit); + rpc GetBlockCommitmentStream(GetBlockCommitmentStreamRequest) returns (stream GetBlockCommitmentStreamResponse); } From aab009aa6ccb9a65d388212429d9ec0b55f99ae3 Mon Sep 17 00:00:00 2001 From: itamar Date: Wed, 2 Oct 2024 14:05:49 -0400 Subject: [PATCH 3/5] split optimistic execution to separate file --- .../src/generated/astria.bundle.v1alpha1.rs | 524 +++++++++--------- .../astria/bundle/v1alpha1/bundle.proto | 35 -- .../v1alpha1/optimistic_execution.proto | 38 ++ 3 files changed, 300 insertions(+), 297 deletions(-) create mode 100644 proto/executionapis/astria/bundle/v1alpha1/optimistic_execution.proto diff --git a/crates/astria-core/src/generated/astria.bundle.v1alpha1.rs b/crates/astria-core/src/generated/astria.bundle.v1alpha1.rs index b4ab725ab2..bedec251e3 100644 --- a/crates/astria-core/src/generated/astria.bundle.v1alpha1.rs +++ b/crates/astria-core/src/generated/astria.bundle.v1alpha1.rs @@ -1,60 +1,3 @@ -/// The "BaseBlock" is the information needed to simulate bundles on top of -/// a Sequencer block which may not have been committed yet. -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct BaseBlock { - /// This is the block hash for the proposed block. - #[prost(bytes = "bytes", tag = "1")] - pub sequencer_block_hash: ::prost::bytes::Bytes, - /// List of transactions to include in the new block. - #[prost(message, repeated, tag = "2")] - pub transactions: ::prost::alloc::vec::Vec< - super::super::sequencerblock::v1alpha1::RollupData, - >, - /// Timestamp to be used for new block. - #[prost(message, optional, tag = "3")] - pub timestamp: ::core::option::Option<::pbjson_types::Timestamp>, -} -impl ::prost::Name for BaseBlock { - const NAME: &'static str = "BaseBlock"; - const PACKAGE: &'static str = "astria.bundle.v1alpha1"; - fn full_name() -> ::prost::alloc::string::String { - ::prost::alloc::format!("astria.bundle.v1alpha1.{}", Self::NAME) - } -} -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct ExecuteOptimisticBlockStreamRequest { - #[prost(message, optional, tag = "1")] - pub base_block: ::core::option::Option, -} -impl ::prost::Name for ExecuteOptimisticBlockStreamRequest { - const NAME: &'static str = "ExecuteOptimisticBlockStreamRequest"; - const PACKAGE: &'static str = "astria.bundle.v1alpha1"; - fn full_name() -> ::prost::alloc::string::String { - ::prost::alloc::format!("astria.bundle.v1alpha1.{}", Self::NAME) - } -} -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct ExecuteOptimisticBlockStreamResponse { - /// Metadata identifying the block resulting from executing a block. Includes number, hash, - /// parent hash and timestamp. - #[prost(message, optional, tag = "1")] - pub block: ::core::option::Option, - /// The base_sequencer_block_hash is the hash from the base sequencer block this block - /// is based on. This is used to associate an optimistic execution result with the hash - /// received once a sequencer block is committed. - #[prost(bytes = "bytes", tag = "2")] - pub base_sequencer_block_hash: ::prost::bytes::Bytes, -} -impl ::prost::Name for ExecuteOptimisticBlockStreamResponse { - const NAME: &'static str = "ExecuteOptimisticBlockStreamResponse"; - const PACKAGE: &'static str = "astria.bundle.v1alpha1"; - fn full_name() -> ::prost::alloc::string::String { - ::prost::alloc::format!("astria.bundle.v1alpha1.{}", Self::NAME) - } -} #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct GetBundleStreamRequest {} @@ -112,132 +55,6 @@ impl ::prost::Name for GetBundleStreamResponse { } /// Generated client implementations. #[cfg(feature = "client")] -pub mod optimistic_execution_service_client { - #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] - use tonic::codegen::*; - use tonic::codegen::http::Uri; - #[derive(Debug, Clone)] - pub struct OptimisticExecutionServiceClient { - inner: tonic::client::Grpc, - } - impl OptimisticExecutionServiceClient { - /// Attempt to create a new client by connecting to a given endpoint. - pub async fn connect(dst: D) -> Result - where - D: TryInto, - D::Error: Into, - { - let conn = tonic::transport::Endpoint::new(dst)?.connect().await?; - Ok(Self::new(conn)) - } - } - impl OptimisticExecutionServiceClient - where - T: tonic::client::GrpcService, - T::Error: Into, - T::ResponseBody: Body + Send + 'static, - ::Error: Into + Send, - { - pub fn new(inner: T) -> Self { - let inner = tonic::client::Grpc::new(inner); - Self { inner } - } - pub fn with_origin(inner: T, origin: Uri) -> Self { - let inner = tonic::client::Grpc::with_origin(inner, origin); - Self { inner } - } - pub fn with_interceptor( - inner: T, - interceptor: F, - ) -> OptimisticExecutionServiceClient> - where - F: tonic::service::Interceptor, - T::ResponseBody: Default, - T: tonic::codegen::Service< - http::Request, - Response = http::Response< - >::ResponseBody, - >, - >, - , - >>::Error: Into + Send + Sync, - { - OptimisticExecutionServiceClient::new( - InterceptedService::new(inner, interceptor), - ) - } - /// Compress requests with the given encoding. - /// - /// This requires the server to support it otherwise it might respond with an - /// error. - #[must_use] - pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { - self.inner = self.inner.send_compressed(encoding); - self - } - /// Enable decompressing responses. - #[must_use] - pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { - self.inner = self.inner.accept_compressed(encoding); - self - } - /// Limits the maximum size of a decoded message. - /// - /// Default: `4MB` - #[must_use] - pub fn max_decoding_message_size(mut self, limit: usize) -> Self { - self.inner = self.inner.max_decoding_message_size(limit); - self - } - /// Limits the maximum size of an encoded message. - /// - /// Default: `usize::MAX` - #[must_use] - pub fn max_encoding_message_size(mut self, limit: usize) -> Self { - self.inner = self.inner.max_encoding_message_size(limit); - self - } - /// Stream blocks from the Auctioneer to Geth for optimistic execution. Geth will stream back - /// metadata from the executed blocks. - pub async fn execute_optimistic_block_stream( - &mut self, - request: impl tonic::IntoStreamingRequest< - Message = super::ExecuteOptimisticBlockStreamRequest, - >, - ) -> std::result::Result< - tonic::Response< - tonic::codec::Streaming, - >, - tonic::Status, - > { - self.inner - .ready() - .await - .map_err(|e| { - tonic::Status::new( - tonic::Code::Unknown, - format!("Service was not ready: {}", e.into()), - ) - })?; - let codec = tonic::codec::ProstCodec::default(); - let path = http::uri::PathAndQuery::from_static( - "/astria.bundle.v1alpha1.OptimisticExecutionService/ExecuteOptimisticBlockStream", - ); - let mut req = request.into_streaming_request(); - req.extensions_mut() - .insert( - GrpcMethod::new( - "astria.bundle.v1alpha1.OptimisticExecutionService", - "ExecuteOptimisticBlockStream", - ), - ); - self.inner.streaming(req, path, codec).await - } - } -} -/// Generated client implementations. -#[cfg(feature = "client")] pub mod bundle_service_client { #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] use tonic::codegen::*; @@ -359,35 +176,31 @@ pub mod bundle_service_client { } /// Generated server implementations. #[cfg(feature = "server")] -pub mod optimistic_execution_service_server { +pub mod bundle_service_server { #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] use tonic::codegen::*; - /// Generated trait containing gRPC methods that should be implemented for use with OptimisticExecutionServiceServer. + /// Generated trait containing gRPC methods that should be implemented for use with BundleServiceServer. #[async_trait] - pub trait OptimisticExecutionService: Send + Sync + 'static { - /// Server streaming response type for the ExecuteOptimisticBlockStream method. - type ExecuteOptimisticBlockStreamStream: tonic::codegen::tokio_stream::Stream< - Item = std::result::Result< - super::ExecuteOptimisticBlockStreamResponse, - tonic::Status, - >, + pub trait BundleService: Send + Sync + 'static { + /// Server streaming response type for the GetBundleStream method. + type GetBundleStreamStream: tonic::codegen::tokio_stream::Stream< + Item = std::result::Result, > + Send + 'static; - /// Stream blocks from the Auctioneer to Geth for optimistic execution. Geth will stream back - /// metadata from the executed blocks. - async fn execute_optimistic_block_stream( + /// A bundle submitter requests bundles given a new optimistic Sequencer block, + /// and receives a stream of potential bundles for submission, until either a timeout + /// or the connection is closed by the client. + async fn get_bundle_stream( self: std::sync::Arc, - request: tonic::Request< - tonic::Streaming, - >, + request: tonic::Request, ) -> std::result::Result< - tonic::Response, + tonic::Response, tonic::Status, >; } #[derive(Debug)] - pub struct OptimisticExecutionServiceServer { + pub struct BundleServiceServer { inner: _Inner, accept_compression_encodings: EnabledCompressionEncodings, send_compression_encodings: EnabledCompressionEncodings, @@ -395,7 +208,7 @@ pub mod optimistic_execution_service_server { max_encoding_message_size: Option, } struct _Inner(Arc); - impl OptimisticExecutionServiceServer { + impl BundleServiceServer { pub fn new(inner: T) -> Self { Self::from_arc(Arc::new(inner)) } @@ -447,10 +260,9 @@ pub mod optimistic_execution_service_server { self } } - impl tonic::codegen::Service> - for OptimisticExecutionServiceServer + impl tonic::codegen::Service> for BundleServiceServer where - T: OptimisticExecutionService, + T: BundleService, B: Body + Send + 'static, B::Error: Into + Send + 'static, { @@ -466,36 +278,27 @@ pub mod optimistic_execution_service_server { fn call(&mut self, req: http::Request) -> Self::Future { let inner = self.inner.clone(); match req.uri().path() { - "/astria.bundle.v1alpha1.OptimisticExecutionService/ExecuteOptimisticBlockStream" => { + "/astria.bundle.v1alpha1.BundleService/GetBundleStream" => { #[allow(non_camel_case_types)] - struct ExecuteOptimisticBlockStreamSvc< - T: OptimisticExecutionService, - >( - pub Arc, - ); + struct GetBundleStreamSvc(pub Arc); impl< - T: OptimisticExecutionService, - > tonic::server::StreamingService< - super::ExecuteOptimisticBlockStreamRequest, - > for ExecuteOptimisticBlockStreamSvc { - type Response = super::ExecuteOptimisticBlockStreamResponse; - type ResponseStream = T::ExecuteOptimisticBlockStreamStream; + T: BundleService, + > tonic::server::ServerStreamingService< + super::GetBundleStreamRequest, + > for GetBundleStreamSvc { + type Response = super::GetBundleStreamResponse; + type ResponseStream = T::GetBundleStreamStream; type Future = BoxFuture< tonic::Response, tonic::Status, >; fn call( &mut self, - request: tonic::Request< - tonic::Streaming, - >, + request: tonic::Request, ) -> Self::Future { let inner = Arc::clone(&self.0); let fut = async move { - ::execute_optimistic_block_stream( - inner, - request, - ) + ::get_bundle_stream(inner, request) .await }; Box::pin(fut) @@ -508,7 +311,7 @@ pub mod optimistic_execution_service_server { let inner = self.inner.clone(); let fut = async move { let inner = inner.0; - let method = ExecuteOptimisticBlockStreamSvc(inner); + let method = GetBundleStreamSvc(inner); let codec = tonic::codec::ProstCodec::default(); let mut grpc = tonic::server::Grpc::new(codec) .apply_compression_config( @@ -519,7 +322,7 @@ pub mod optimistic_execution_service_server { max_decoding_message_size, max_encoding_message_size, ); - let res = grpc.streaming(method, req).await; + let res = grpc.server_streaming(method, req).await; Ok(res) }; Box::pin(fut) @@ -539,7 +342,7 @@ pub mod optimistic_execution_service_server { } } } - impl Clone for OptimisticExecutionServiceServer { + impl Clone for BundleServiceServer { fn clone(&self) -> Self { let inner = self.inner.clone(); Self { @@ -551,7 +354,7 @@ pub mod optimistic_execution_service_server { } } } - impl Clone for _Inner { + impl Clone for _Inner { fn clone(&self) -> Self { Self(Arc::clone(&self.0)) } @@ -561,38 +364,224 @@ pub mod optimistic_execution_service_server { write!(f, "{:?}", self.0) } } - impl tonic::server::NamedService - for OptimisticExecutionServiceServer { - const NAME: &'static str = "astria.bundle.v1alpha1.OptimisticExecutionService"; + impl tonic::server::NamedService for BundleServiceServer { + const NAME: &'static str = "astria.bundle.v1alpha1.BundleService"; + } +} +/// The "BaseBlock" is the information needed to simulate bundles on top of +/// a Sequencer block which may not have been committed yet. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct BaseBlock { + /// This is the block hash for the proposed block. + #[prost(bytes = "bytes", tag = "1")] + pub sequencer_block_hash: ::prost::bytes::Bytes, + /// List of transactions to include in the new block. + #[prost(message, repeated, tag = "2")] + pub transactions: ::prost::alloc::vec::Vec< + super::super::sequencerblock::v1alpha1::RollupData, + >, + /// Timestamp to be used for new block. + #[prost(message, optional, tag = "3")] + pub timestamp: ::core::option::Option<::pbjson_types::Timestamp>, +} +impl ::prost::Name for BaseBlock { + const NAME: &'static str = "BaseBlock"; + const PACKAGE: &'static str = "astria.bundle.v1alpha1"; + fn full_name() -> ::prost::alloc::string::String { + ::prost::alloc::format!("astria.bundle.v1alpha1.{}", Self::NAME) + } +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ExecuteOptimisticBlockStreamRequest { + #[prost(message, optional, tag = "1")] + pub base_block: ::core::option::Option, +} +impl ::prost::Name for ExecuteOptimisticBlockStreamRequest { + const NAME: &'static str = "ExecuteOptimisticBlockStreamRequest"; + const PACKAGE: &'static str = "astria.bundle.v1alpha1"; + fn full_name() -> ::prost::alloc::string::String { + ::prost::alloc::format!("astria.bundle.v1alpha1.{}", Self::NAME) + } +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ExecuteOptimisticBlockStreamResponse { + /// Metadata identifying the block resulting from executing a block. Includes number, hash, + /// parent hash and timestamp. + #[prost(message, optional, tag = "1")] + pub block: ::core::option::Option, + /// The base_sequencer_block_hash is the hash from the base sequencer block this block + /// is based on. This is used to associate an optimistic execution result with the hash + /// received once a sequencer block is committed. + #[prost(bytes = "bytes", tag = "2")] + pub base_sequencer_block_hash: ::prost::bytes::Bytes, +} +impl ::prost::Name for ExecuteOptimisticBlockStreamResponse { + const NAME: &'static str = "ExecuteOptimisticBlockStreamResponse"; + const PACKAGE: &'static str = "astria.bundle.v1alpha1"; + fn full_name() -> ::prost::alloc::string::String { + ::prost::alloc::format!("astria.bundle.v1alpha1.{}", Self::NAME) + } +} +/// Generated client implementations. +#[cfg(feature = "client")] +pub mod optimistic_execution_service_client { + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] + use tonic::codegen::*; + use tonic::codegen::http::Uri; + #[derive(Debug, Clone)] + pub struct OptimisticExecutionServiceClient { + inner: tonic::client::Grpc, + } + impl OptimisticExecutionServiceClient { + /// Attempt to create a new client by connecting to a given endpoint. + pub async fn connect(dst: D) -> Result + where + D: TryInto, + D::Error: Into, + { + let conn = tonic::transport::Endpoint::new(dst)?.connect().await?; + Ok(Self::new(conn)) + } + } + impl OptimisticExecutionServiceClient + where + T: tonic::client::GrpcService, + T::Error: Into, + T::ResponseBody: Body + Send + 'static, + ::Error: Into + Send, + { + pub fn new(inner: T) -> Self { + let inner = tonic::client::Grpc::new(inner); + Self { inner } + } + pub fn with_origin(inner: T, origin: Uri) -> Self { + let inner = tonic::client::Grpc::with_origin(inner, origin); + Self { inner } + } + pub fn with_interceptor( + inner: T, + interceptor: F, + ) -> OptimisticExecutionServiceClient> + where + F: tonic::service::Interceptor, + T::ResponseBody: Default, + T: tonic::codegen::Service< + http::Request, + Response = http::Response< + >::ResponseBody, + >, + >, + , + >>::Error: Into + Send + Sync, + { + OptimisticExecutionServiceClient::new( + InterceptedService::new(inner, interceptor), + ) + } + /// Compress requests with the given encoding. + /// + /// This requires the server to support it otherwise it might respond with an + /// error. + #[must_use] + pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.inner = self.inner.send_compressed(encoding); + self + } + /// Enable decompressing responses. + #[must_use] + pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.inner = self.inner.accept_compressed(encoding); + self + } + /// Limits the maximum size of a decoded message. + /// + /// Default: `4MB` + #[must_use] + pub fn max_decoding_message_size(mut self, limit: usize) -> Self { + self.inner = self.inner.max_decoding_message_size(limit); + self + } + /// Limits the maximum size of an encoded message. + /// + /// Default: `usize::MAX` + #[must_use] + pub fn max_encoding_message_size(mut self, limit: usize) -> Self { + self.inner = self.inner.max_encoding_message_size(limit); + self + } + /// Stream blocks from the Auctioneer to Geth for optimistic execution. Geth will stream back + /// metadata from the executed blocks. + pub async fn execute_optimistic_block_stream( + &mut self, + request: impl tonic::IntoStreamingRequest< + Message = super::ExecuteOptimisticBlockStreamRequest, + >, + ) -> std::result::Result< + tonic::Response< + tonic::codec::Streaming, + >, + tonic::Status, + > { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::new( + tonic::Code::Unknown, + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/astria.bundle.v1alpha1.OptimisticExecutionService/ExecuteOptimisticBlockStream", + ); + let mut req = request.into_streaming_request(); + req.extensions_mut() + .insert( + GrpcMethod::new( + "astria.bundle.v1alpha1.OptimisticExecutionService", + "ExecuteOptimisticBlockStream", + ), + ); + self.inner.streaming(req, path, codec).await + } } } /// Generated server implementations. #[cfg(feature = "server")] -pub mod bundle_service_server { +pub mod optimistic_execution_service_server { #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] use tonic::codegen::*; - /// Generated trait containing gRPC methods that should be implemented for use with BundleServiceServer. + /// Generated trait containing gRPC methods that should be implemented for use with OptimisticExecutionServiceServer. #[async_trait] - pub trait BundleService: Send + Sync + 'static { - /// Server streaming response type for the GetBundleStream method. - type GetBundleStreamStream: tonic::codegen::tokio_stream::Stream< - Item = std::result::Result, + pub trait OptimisticExecutionService: Send + Sync + 'static { + /// Server streaming response type for the ExecuteOptimisticBlockStream method. + type ExecuteOptimisticBlockStreamStream: tonic::codegen::tokio_stream::Stream< + Item = std::result::Result< + super::ExecuteOptimisticBlockStreamResponse, + tonic::Status, + >, > + Send + 'static; - /// A bundle submitter requests bundles given a new optimistic Sequencer block, - /// and receives a stream of potential bundles for submission, until either a timeout - /// or the connection is closed by the client. - async fn get_bundle_stream( + /// Stream blocks from the Auctioneer to Geth for optimistic execution. Geth will stream back + /// metadata from the executed blocks. + async fn execute_optimistic_block_stream( self: std::sync::Arc, - request: tonic::Request, + request: tonic::Request< + tonic::Streaming, + >, ) -> std::result::Result< - tonic::Response, + tonic::Response, tonic::Status, >; } #[derive(Debug)] - pub struct BundleServiceServer { + pub struct OptimisticExecutionServiceServer { inner: _Inner, accept_compression_encodings: EnabledCompressionEncodings, send_compression_encodings: EnabledCompressionEncodings, @@ -600,7 +589,7 @@ pub mod bundle_service_server { max_encoding_message_size: Option, } struct _Inner(Arc); - impl BundleServiceServer { + impl OptimisticExecutionServiceServer { pub fn new(inner: T) -> Self { Self::from_arc(Arc::new(inner)) } @@ -652,9 +641,10 @@ pub mod bundle_service_server { self } } - impl tonic::codegen::Service> for BundleServiceServer + impl tonic::codegen::Service> + for OptimisticExecutionServiceServer where - T: BundleService, + T: OptimisticExecutionService, B: Body + Send + 'static, B::Error: Into + Send + 'static, { @@ -670,27 +660,36 @@ pub mod bundle_service_server { fn call(&mut self, req: http::Request) -> Self::Future { let inner = self.inner.clone(); match req.uri().path() { - "/astria.bundle.v1alpha1.BundleService/GetBundleStream" => { + "/astria.bundle.v1alpha1.OptimisticExecutionService/ExecuteOptimisticBlockStream" => { #[allow(non_camel_case_types)] - struct GetBundleStreamSvc(pub Arc); + struct ExecuteOptimisticBlockStreamSvc< + T: OptimisticExecutionService, + >( + pub Arc, + ); impl< - T: BundleService, - > tonic::server::ServerStreamingService< - super::GetBundleStreamRequest, - > for GetBundleStreamSvc { - type Response = super::GetBundleStreamResponse; - type ResponseStream = T::GetBundleStreamStream; + T: OptimisticExecutionService, + > tonic::server::StreamingService< + super::ExecuteOptimisticBlockStreamRequest, + > for ExecuteOptimisticBlockStreamSvc { + type Response = super::ExecuteOptimisticBlockStreamResponse; + type ResponseStream = T::ExecuteOptimisticBlockStreamStream; type Future = BoxFuture< tonic::Response, tonic::Status, >; fn call( &mut self, - request: tonic::Request, + request: tonic::Request< + tonic::Streaming, + >, ) -> Self::Future { let inner = Arc::clone(&self.0); let fut = async move { - ::get_bundle_stream(inner, request) + ::execute_optimistic_block_stream( + inner, + request, + ) .await }; Box::pin(fut) @@ -703,7 +702,7 @@ pub mod bundle_service_server { let inner = self.inner.clone(); let fut = async move { let inner = inner.0; - let method = GetBundleStreamSvc(inner); + let method = ExecuteOptimisticBlockStreamSvc(inner); let codec = tonic::codec::ProstCodec::default(); let mut grpc = tonic::server::Grpc::new(codec) .apply_compression_config( @@ -714,7 +713,7 @@ pub mod bundle_service_server { max_decoding_message_size, max_encoding_message_size, ); - let res = grpc.server_streaming(method, req).await; + let res = grpc.streaming(method, req).await; Ok(res) }; Box::pin(fut) @@ -734,7 +733,7 @@ pub mod bundle_service_server { } } } - impl Clone for BundleServiceServer { + impl Clone for OptimisticExecutionServiceServer { fn clone(&self) -> Self { let inner = self.inner.clone(); Self { @@ -746,7 +745,7 @@ pub mod bundle_service_server { } } } - impl Clone for _Inner { + impl Clone for _Inner { fn clone(&self) -> Self { Self(Arc::clone(&self.0)) } @@ -756,7 +755,8 @@ pub mod bundle_service_server { write!(f, "{:?}", self.0) } } - impl tonic::server::NamedService for BundleServiceServer { - const NAME: &'static str = "astria.bundle.v1alpha1.BundleService"; + impl tonic::server::NamedService + for OptimisticExecutionServiceServer { + const NAME: &'static str = "astria.bundle.v1alpha1.OptimisticExecutionService"; } } diff --git a/proto/executionapis/astria/bundle/v1alpha1/bundle.proto b/proto/executionapis/astria/bundle/v1alpha1/bundle.proto index beb5718de4..f4d350803f 100644 --- a/proto/executionapis/astria/bundle/v1alpha1/bundle.proto +++ b/proto/executionapis/astria/bundle/v1alpha1/bundle.proto @@ -2,35 +2,6 @@ syntax = "proto3"; package astria.bundle.v1alpha1; -import "astria/execution/v1alpha2/execution.proto"; -import "astria/sequencerblock/v1alpha1/block.proto"; -import "google/protobuf/timestamp.proto"; - -// The "BaseBlock" is the information needed to simulate bundles on top of -// a Sequencer block which may not have been committed yet. -message BaseBlock { - // This is the block hash for the proposed block. - bytes sequencer_block_hash = 1; - // List of transactions to include in the new block. - repeated astria.sequencerblock.v1alpha1.RollupData transactions = 2; - // Timestamp to be used for new block. - google.protobuf.Timestamp timestamp = 3; -} - -message ExecuteOptimisticBlockStreamRequest { - BaseBlock base_block = 1; -} - -message ExecuteOptimisticBlockStreamResponse { - // Metadata identifying the block resulting from executing a block. Includes number, hash, - // parent hash and timestamp. - astria.execution.v1alpha2.Block block = 1; - // The base_sequencer_block_hash is the hash from the base sequencer block this block - // is based on. This is used to associate an optimistic execution result with the hash - // received once a sequencer block is committed. - bytes base_sequencer_block_hash = 2; -} - message GetBundleStreamRequest {} // Information for the bundle submitter to know how to submit the bundle. @@ -57,12 +28,6 @@ message GetBundleStreamResponse { Bundle bundle = 1; } -service OptimisticExecutionService { - // Stream blocks from the Auctioneer to Geth for optimistic execution. Geth will stream back - // metadata from the executed blocks. - rpc ExecuteOptimisticBlockStream(stream ExecuteOptimisticBlockStreamRequest) returns (stream ExecuteOptimisticBlockStreamResponse); -} - service BundleService { // A bundle submitter requests bundles given a new optimistic Sequencer block, // and receives a stream of potential bundles for submission, until either a timeout diff --git a/proto/executionapis/astria/bundle/v1alpha1/optimistic_execution.proto b/proto/executionapis/astria/bundle/v1alpha1/optimistic_execution.proto new file mode 100644 index 0000000000..c944dff8e3 --- /dev/null +++ b/proto/executionapis/astria/bundle/v1alpha1/optimistic_execution.proto @@ -0,0 +1,38 @@ +syntax = "proto3"; + +package astria.bundle.v1alpha1; + +import "astria/execution/v1alpha2/execution.proto"; +import "astria/sequencerblock/v1alpha1/block.proto"; +import "google/protobuf/timestamp.proto"; + +// The "BaseBlock" is the information needed to simulate bundles on top of +// a Sequencer block which may not have been committed yet. +message BaseBlock { + // This is the block hash for the proposed block. + bytes sequencer_block_hash = 1; + // List of transactions to include in the new block. + repeated astria.sequencerblock.v1alpha1.RollupData transactions = 2; + // Timestamp to be used for new block. + google.protobuf.Timestamp timestamp = 3; +} + +message ExecuteOptimisticBlockStreamRequest { + BaseBlock base_block = 1; +} + +message ExecuteOptimisticBlockStreamResponse { + // Metadata identifying the block resulting from executing a block. Includes number, hash, + // parent hash and timestamp. + astria.execution.v1alpha2.Block block = 1; + // The base_sequencer_block_hash is the hash from the base sequencer block this block + // is based on. This is used to associate an optimistic execution result with the hash + // received once a sequencer block is committed. + bytes base_sequencer_block_hash = 2; +} + +service OptimisticExecutionService { + // Stream blocks from the Auctioneer to Geth for optimistic execution. Geth will stream back + // metadata from the executed blocks. + rpc ExecuteOptimisticBlockStream(stream ExecuteOptimisticBlockStreamRequest) returns (stream ExecuteOptimisticBlockStreamResponse); +} From 9f1c7682574d18a129aa5e82ee21b79de0227e98 Mon Sep 17 00:00:00 2001 From: itamar Date: Wed, 2 Oct 2024 15:06:29 -0400 Subject: [PATCH 4/5] add module to astria_core --- crates/astria-core/src/generated/mod.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/crates/astria-core/src/generated/mod.rs b/crates/astria-core/src/generated/mod.rs index 4b78c07fe0..690c9c09b0 100644 --- a/crates/astria-core/src/generated/mod.rs +++ b/crates/astria-core/src/generated/mod.rs @@ -37,6 +37,19 @@ pub mod astria_vendored { } } +#[path = ""] +pub mod bundle { + pub mod v1lapha1 { + include!("astria.bundle.v1alpha1.rs"); + + #[cfg(feature = "serde")] + mod _serde_impl { + use super::*; + include!("astria.bundle.v1alpha1.serde.rs"); + } + } +} + #[path = ""] pub mod execution { #[path = "astria.execution.v1alpha1.rs"] From 69b4ecddbfa091a94339812d46ec6c7ae92ebd1a Mon Sep 17 00:00:00 2001 From: itamar Date: Wed, 2 Oct 2024 16:35:49 -0400 Subject: [PATCH 5/5] typo fix --- crates/astria-core/src/generated/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/astria-core/src/generated/mod.rs b/crates/astria-core/src/generated/mod.rs index 690c9c09b0..b48248efc8 100644 --- a/crates/astria-core/src/generated/mod.rs +++ b/crates/astria-core/src/generated/mod.rs @@ -39,7 +39,7 @@ pub mod astria_vendored { #[path = ""] pub mod bundle { - pub mod v1lapha1 { + pub mod v1alpha1 { include!("astria.bundle.v1alpha1.rs"); #[cfg(feature = "serde")]