Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

tendermint-proto: grpc server definitions for rpc/abci #1338

Merged
merged 11 commits into from
Aug 29, 2023
2 changes: 2 additions & 0 deletions .changelog/unreleased/features/1338-grpc-server-rpc-abci.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- `[tendermint-proto]` add `grpc`/`grpc-server` features to include gRPC server definitions for the RPC/ABCI services.
([#1338](https://github.com/informalsystems/tendermint-rs/issues/1338))
6 changes: 6 additions & 0 deletions proto/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ description = """
tendermint-proto is a the Rust implementation of the Tendermint proto structs.
"""

[features]
default = []
grpc = ["grpc-server"]
grpc-server = ["tonic"]

[package.metadata.docs.rs]
all-features = true

Expand All @@ -27,6 +32,7 @@ num-traits = { version = "0.2", default-features = false }
num-derive = { version = "0.3", default-features = false }
time = { version = "0.3", default-features = false, features = ["macros", "parsing"] }
flex-error = { version = "0.4.4", default-features = false }
tonic = { version = "0.9", optional = true }

[dev-dependencies]
serde_json = { version = "1.0", default-features = false, features = ["alloc"] }
2 changes: 1 addition & 1 deletion proto/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! tendermint-proto library gives the developer access to the Tendermint proto-defined structs.

#![no_std]
#![cfg_attr(not(any(feature = "grpc-server", feature = "grpc-client")), no_std)]
#![deny(warnings, trivial_casts, trivial_numeric_casts, unused_import_braces)]
#![allow(clippy::large_enum_variant)]
#![forbid(unsafe_code)]
Expand Down
880 changes: 880 additions & 0 deletions proto/src/prost/v0_34/tendermint.abci.rs

Large diffs are not rendered by default.

228 changes: 228 additions & 0 deletions proto/src/prost/v0_34/tendermint.rpc.grpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,231 @@ pub struct ResponseBroadcastTx {
#[prost(message, optional, tag = "2")]
pub deliver_tx: ::core::option::Option<super::super::abci::ResponseDeliverTx>,
}
/// Generated server implementations.
#[cfg(feature = "grpc-server")]
pub mod broadcast_api_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 BroadcastApiServer.
#[async_trait]
pub trait BroadcastApi: Send + Sync + 'static {
async fn ping(
&self,
request: tonic::Request<super::RequestPing>,
) -> std::result::Result<tonic::Response<super::ResponsePing>, tonic::Status>;
async fn broadcast_tx(
&self,
request: tonic::Request<super::RequestBroadcastTx>,
) -> std::result::Result<
tonic::Response<super::ResponseBroadcastTx>,
tonic::Status,
>;
}
#[derive(Debug)]
pub struct BroadcastApiServer<T: BroadcastApi> {
inner: _Inner<T>,
accept_compression_encodings: EnabledCompressionEncodings,
send_compression_encodings: EnabledCompressionEncodings,
max_decoding_message_size: Option<usize>,
max_encoding_message_size: Option<usize>,
}
struct _Inner<T>(Arc<T>);
impl<T: BroadcastApi> BroadcastApiServer<T> {
pub fn new(inner: T) -> Self {
Self::from_arc(Arc::new(inner))
}
pub fn from_arc(inner: Arc<T>) -> 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<F>(
inner: T,
interceptor: F,
) -> InterceptedService<Self, F>
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<T, B> tonic::codegen::Service<http::Request<B>> for BroadcastApiServer<T>
where
T: BroadcastApi,
B: Body + Send + 'static,
B::Error: Into<StdError> + Send + 'static,
{
type Response = http::Response<tonic::body::BoxBody>;
type Error = std::convert::Infallible;
type Future = BoxFuture<Self::Response, Self::Error>;
fn poll_ready(
&mut self,
_cx: &mut Context<'_>,
) -> Poll<std::result::Result<(), Self::Error>> {
Poll::Ready(Ok(()))
}
fn call(&mut self, req: http::Request<B>) -> Self::Future {
let inner = self.inner.clone();
match req.uri().path() {
"/tendermint.rpc.grpc.BroadcastAPI/Ping" => {
#[allow(non_camel_case_types)]
struct PingSvc<T: BroadcastApi>(pub Arc<T>);
impl<T: BroadcastApi> tonic::server::UnaryService<super::RequestPing>
for PingSvc<T> {
type Response = super::ResponsePing;
type Future = BoxFuture<
tonic::Response<Self::Response>,
tonic::Status,
>;
fn call(
&mut self,
request: tonic::Request<super::RequestPing>,
) -> Self::Future {
let inner = Arc::clone(&self.0);
let fut = async move { (*inner).ping(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 = PingSvc(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.unary(method, req).await;
Ok(res)
};
Box::pin(fut)
}
"/tendermint.rpc.grpc.BroadcastAPI/BroadcastTx" => {
#[allow(non_camel_case_types)]
struct BroadcastTxSvc<T: BroadcastApi>(pub Arc<T>);
impl<
T: BroadcastApi,
> tonic::server::UnaryService<super::RequestBroadcastTx>
for BroadcastTxSvc<T> {
type Response = super::ResponseBroadcastTx;
type Future = BoxFuture<
tonic::Response<Self::Response>,
tonic::Status,
>;
fn call(
&mut self,
request: tonic::Request<super::RequestBroadcastTx>,
) -> Self::Future {
let inner = Arc::clone(&self.0);
let fut = async move {
(*inner).broadcast_tx(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 = BroadcastTxSvc(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.unary(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<T: BroadcastApi> Clone for BroadcastApiServer<T> {
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<T: BroadcastApi> Clone for _Inner<T> {
fn clone(&self) -> Self {
Self(Arc::clone(&self.0))
}
}
impl<T: std::fmt::Debug> std::fmt::Debug for _Inner<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self.0)
}
}
impl<T: BroadcastApi> tonic::server::NamedService for BroadcastApiServer<T> {
const NAME: &'static str = "tendermint.rpc.grpc.BroadcastAPI";
}
}
Loading