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

feat(proto)!: separate client and server feature #118

Open
wants to merge 8 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion abci/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,11 @@ server = [
"dep:tokio",
"dep:tokio-util",
"dep:futures",
"grpc",
]
# std is deprecated, use "grpc" instead
std = ["grpc"]
grpc = ["tenderdash-proto/grpc"]
grpc = ["tenderdash-proto/server"]
crypto = ["dep:lhash"]
tcp = ["server"]
unix = ["server"]
Expand Down
18 changes: 16 additions & 2 deletions abci/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,27 @@ pub enum Error {
#[error("connection error")]
Connection(#[from] io::Error),
#[error("cannot decode protobuf message")]
Decode(#[from] DecodeError),
Decode(DecodeError),
#[error("cannot encode protobuf message")]
Encode(#[from] EncodeError),
Encode(EncodeError),
#[error("cannot create canonical message: {0}")]
Canonical(String),
#[error("server terminated")]
Cancelled(),
#[error("async runtime error")]
Async(String),
}

// manually implemented due to no_std compatibility
impl From<EncodeError> for Error {
fn from(error: EncodeError) -> Error {
Error::Encode(error)
}
}

// manually implemented due to no_std compatibility
impl From<DecodeError> for Error {
fn from(error: DecodeError) -> Error {
Error::Decode(error)
}
}
2 changes: 1 addition & 1 deletion abci/src/server/generic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ impl<App: RequestDispatcher> GenericServer<App, UnixListener> {
}
}

impl<'a, App: RequestDispatcher + 'a, L: Listener> Server for GenericServer<App, L>
impl<App: RequestDispatcher, L: Listener> Server for GenericServer<App, L>
where
L: Listener + Send + Sync + 'static,
L::Addr: Send + Debug,
Expand Down
5 changes: 0 additions & 5 deletions proto-compiler/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,4 @@ tonic-build = { version = "0.12.3", optional = true }
[features]
default = []
# Enable gRPC support; needed by server and client features.
# Conflicts with no_std
grpc = ["dep:tonic-build"]
# Build the gRPC server. Requires tenderdash-proto/grpc feature.
server = ["grpc"]
# Build the gRPC client. Requires tenderdash-proto/grpc feature.
client = ["grpc"]
23 changes: 16 additions & 7 deletions proto-compiler/src/constants.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
//! Tenderdash protobuf implementation

use std::fmt::Display;

// Requirements
pub const DEP_PROTOC_VERSION: f32 = 25.0;

Expand All @@ -11,26 +13,33 @@ pub const TENDERDASH_REPO: &str = "https://github.com/dashpay/tenderdash";
pub enum GenerationMode {
/// Generate the files using `tonic` and put them into `tenderdash_grpc`
/// module.
Grpc,
GrpcServer,
/// Generate minimal gRPC client using tonic, without transport
/// implementation. Put them into `tenderdash_grpc_client` module.
GrpcClient,
/// Generate the files without `std` and put them into `tenderdash_nostd`
/// module.
NoStd,
}

impl GenerationMode {
pub fn module_name(&self) -> String {
match self {
GenerationMode::Grpc => "tenderdash_grpc".to_string(),
GenerationMode::GrpcServer => "tenderdash_grpc".to_string(),
GenerationMode::GrpcClient => "tenderdash_grpc_client".to_string(),
GenerationMode::NoStd => "tenderdash_nostd".to_string(),
}
}
}

impl ToString for GenerationMode {
fn to_string(&self) -> String {
match self {
GenerationMode::Grpc => "tonic".to_string(),
impl Display for GenerationMode {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mode = match self {
GenerationMode::GrpcServer => "grpc-client-server".to_string(),
GenerationMode::GrpcClient => "grpc-client".to_string(),
GenerationMode::NoStd => "nostd".to_string(),
}
};
write!(f, "{}", mode)
}
}

Expand Down
19 changes: 17 additions & 2 deletions proto-compiler/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,14 +124,29 @@ pub fn proto_compile(mode: GenerationMode) {
println!("[info] => Creating structs.");

match mode {
GenerationMode::Grpc => {
GenerationMode::GrpcServer => {
#[cfg(feature = "grpc")]
tonic_build::configure()
.build_client(true)
.build_server(true)
.build_transport(true)
.generate_default_stubs(true)
.compile_protos_with_config(pb, &protos, &proto_includes_paths)
.unwrap();
#[cfg(not(feature = "grpc"))]
panic!("grpc feature is required to compile {}", mode.to_string());
panic!("grpc feature is required to compile {}", mode);
},
GenerationMode::GrpcClient => {
#[cfg(feature = "grpc")]
tonic_build::configure()
.build_client(true)
.build_server(false)
.build_transport(false)
.generate_default_stubs(true)
.compile_protos_with_config(pb, &protos, &proto_includes_paths)
.unwrap();
#[cfg(not(feature = "grpc"))]
panic!("grpc feature is required to compile {}", mode);
},
GenerationMode::NoStd => {
pb.compile_protos(&protos, &proto_includes_paths).unwrap();
Expand Down
21 changes: 10 additions & 11 deletions proto/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,16 @@ all-features = true
#
# Sometimes cleaning the build cache with `cargo clean` might be necessary to solve
# issues related to outdated generated files.
default = ["grpc"]
default = ["server"]

# Enable standard library support; DEPRECATED - use `grpc` instead
std = ["grpc"]
# Build gRPC server using tonic
grpc = [
"prost/std",
"tenderdash-proto-compiler/server",
"tenderdash-proto-compiler/client",
"dep:tonic",
]
# Enable standard library support; DEPRECATED - use `client` and/or `server` instead
std = ["client"]
# Enable gRPC support using tonic; internal, consider using `server` or `client` instead
grpc = ["client", "dep:tonic", "tonic/codegen", "tonic/prost"]
# Build gRPC server using tonic. Includes `client` feature.
server = ["client", "tonic/transport"]
# Build minimal gRPC client using tonic, without transport
client = ["tenderdash-proto-compiler/grpc", "prost/std", "grpc"]

serde = ["dep:serde", "bytes/serde"]

Expand All @@ -53,7 +52,7 @@ bytes = { version = "1.7", default-features = false }
prost = { version = "0.13", default-features = false, features = [
"prost-derive",
] }
tonic = { version = "0.12.3", optional = true }
tonic = { version = "0.12.3", optional = true, default-features = false }
serde = { version = "1.0.208", default-features = false, features = [
"derive",
], optional = true }
Expand Down
12 changes: 10 additions & 2 deletions proto/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,16 @@ fn main() {
env::set_var("TENDERDASH_COMMITISH", DEFAULT_VERSION);
}

#[cfg(feature = "grpc")]
tenderdash_proto_compiler::proto_compile(GenerationMode::Grpc);
// build gRPC server and client
// note it should be safe to build both server and client; we will just not use
// them in the lib.rs

#[cfg(feature = "server")]
// build gRPC server (includes client)
tenderdash_proto_compiler::proto_compile(GenerationMode::GrpcServer);
#[cfg(feature = "client")]
// build gRPC client only
tenderdash_proto_compiler::proto_compile(GenerationMode::GrpcClient);
// we always build nostd version
tenderdash_proto_compiler::proto_compile(GenerationMode::NoStd);

Expand Down
1 change: 1 addition & 0 deletions proto/src/.gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
tenderdash_nostd/
tenderdash_grpc/
tenderdash_grpc_client/

# prost/ and tenderdash.rs are deprecated and can be removed in the future
prost/
Expand Down
25 changes: 19 additions & 6 deletions proto/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
//! tenderdash-proto library gives the developer access to the Tenderdash
//! proto-defined structs.

#![cfg_attr(not(feature = "grpc"), no_std)]
#![deny(warnings, trivial_casts, trivial_numeric_casts, unused_import_braces)]
#![allow(clippy::large_enum_variant)]
#![allow(clippy::doc_lazy_continuation)]
#![forbid(unsafe_code)]

extern crate alloc;
Expand Down Expand Up @@ -33,17 +33,30 @@ use bytes::{Buf, BufMut};
pub use error::Error;
pub use prost;
use prost::{encoding::encoded_len_varint, Message};

#[cfg(not(any(feature = "server", feature = "client")))]
#[rustfmt::skip]
#[allow(clippy::empty_docs)]
pub mod tenderdash_nostd;
#[cfg(not(feature = "grpc"))]
// Re-export the nostd module only if the std one is not available
pub use tenderdash_nostd::*;

#[cfg(feature = "grpc")]
#[cfg(feature = "server")]
#[rustfmt::skip]
#[allow(clippy::empty_docs)]
pub mod tenderdash_grpc;
#[cfg(feature = "grpc")]
#[cfg(feature = "client")]
#[rustfmt::skip]
#[allow(clippy::empty_docs)]
pub mod tenderdash_grpc_client;

// Now, re-export correct module

#[cfg(feature = "server")]
pub use tenderdash_grpc::*;
#[cfg(all(not(feature = "server"), feature = "client"))]
pub use tenderdash_grpc_client::*;
#[cfg(all(not(feature = "server"), not(feature = "client")))]
pub use tenderdash_nostd::*;

#[cfg(feature = "serde")]
pub mod serializers;
mod time;
Expand Down
5 changes: 4 additions & 1 deletion proto/src/time.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
//! Time conversion traits and functions

// Most likely we build nostd
#[cfg(not(any(feature = "server", feature = "client")))]
use crate::format;
use crate::{google::protobuf::Timestamp, Error};
pub trait ToMillis {
/// Convert protobuf timestamp into milliseconds since epoch

///
/// Note there is a resolution difference, as timestamp uses nanoseconds
///
/// # Arguments
Expand Down
Loading