diff --git a/proto-compiler/Cargo.toml b/proto-compiler/Cargo.toml index 89a746f..0e140c2 100644 --- a/proto-compiler/Cargo.toml +++ b/proto-compiler/Cargo.toml @@ -10,6 +10,7 @@ publish = false [dependencies] walkdir = { version = "2.3" } +prost = { version = "0.12" } prost-build = { version = "0.12" } tempfile = { version = "3.2.0" } regex = { "version" = "1.7.1" } diff --git a/proto-compiler/src/functions.rs b/proto-compiler/src/functions.rs index 33b6a56..57fe95a 100644 --- a/proto-compiler/src/functions.rs +++ b/proto-compiler/src/functions.rs @@ -1,10 +1,11 @@ use std::{ env, - fs::{copy, create_dir_all, read_to_string, remove_dir_all, File}, + fs::{copy, create_dir_all, read, read_to_string, remove_dir_all, File}, io::Write, path::{Path, PathBuf}, }; +use prost::Message; use walkdir::WalkDir; use crate::constants::DEFAULT_TENDERDASH_COMMITISH; @@ -247,6 +248,7 @@ pub fn generate_tenderdash_lib( tenderdash_lib_target: &Path, abci_ver: &str, td_ver: &str, + module_name: &str, ) { let mut file_names = WalkDir::new(prost_dir) .into_iter() @@ -276,11 +278,7 @@ pub fn generate_tenderdash_lib( let mut tab_count = parts.len(); - let mut inner_content = format!( - "{}include!(\"prost/{}\");", - tab.repeat(tab_count), - file_name - ); + let mut inner_content = format!("{}include!(\"./{}\");", tab.repeat(tab_count), file_name); for part in parts { tab_count -= 1; @@ -304,6 +302,8 @@ pub mod meta {{ pub const ABCI_VERSION: &str = \"{}\"; /// Version of Tenderdash server used to generate protobuf configs pub const TENDERDASH_VERSION: &str = \"{}\"; + /// Name of module where generated files are stored; used to distinguish between std and no-std version + pub const TENDERDASH_MODULE_NAME: &str = \"{}\"; }} ", content, @@ -311,6 +311,7 @@ pub mod meta {{ tenderdash_commitish(), abci_ver, td_ver, + module_name, ); let mut file = @@ -328,10 +329,15 @@ pub(crate) fn tenderdash_commitish() -> String { /// Save the commitish of last successful download to a file in a state file, /// located in the `dir` directory and named `download.state`. -pub(crate) fn save_state(dir: &Path, commitish: &str) { +pub(crate) fn save_state(dir: &Path, commitish: &str, module: &str) { let state_file = PathBuf::from(&dir).join("download.state"); - std::fs::write(&state_file, commitish) + let state = StateInfo { + commitish: commitish.to_string(), + module_name: module.to_string(), + }; + + std::fs::write(&state_file, state.encode_to_vec()) .map_err(|e| { println!( "[warn] => Failed to write download.state file {}: {}", @@ -342,16 +348,48 @@ pub(crate) fn save_state(dir: &Path, commitish: &str) { .ok(); } +#[derive(prost::Message)] +struct StateInfo { + #[prost(string, tag = "1")] + commitish: String, + #[prost(string, tag = "2")] + module_name: String, +} + +impl PartialEq for StateInfo { + fn eq(&self, other: &Self) -> bool { + self.commitish == other.commitish && self.module_name == other.module_name + } +} + /// Check if the state file contains the same commitish as the one we are trying /// to download. State file should be located in the `dir` and named /// `download.state` -pub(crate) fn check_state(dir: &Path, commitish: &str) -> bool { +pub(crate) fn check_state(dir: &Path, commitish: &str, module_name: &str) -> bool { let state_file = PathBuf::from(&dir).join("download.state"); - match read_to_string(state_file) { - Ok(content) => { - println!("[info] => Detected Tenderdash version: {}.", content.trim()); - content.eq(commitish) + let expected = StateInfo { + commitish: commitish.to_string(), + module_name: module_name.to_string(), + }; + + match read(&state_file) { + Ok(content) => match StateInfo::decode(content.as_slice()) { + Ok(state) => { + println!( + "[info] => Detected Tenderdash version: {}.", + state.commitish + ); + state.eq(&expected) + }, + Err(e) => { + println!( + "[warn] => Failed to decode download.state file {}: {}", + state_file.display(), + e + ); + false + }, }, Err(_) => false, } diff --git a/proto-compiler/src/lib.rs b/proto-compiler/src/lib.rs index 483ec25..a2ffce2 100644 --- a/proto-compiler/src/lib.rs +++ b/proto-compiler/src/lib.rs @@ -18,16 +18,15 @@ use crate::functions::{check_state, save_state}; /// Checkouts tenderdash repository to ../target/tenderdash and generates /// Rust protobuf definitions in ../proto/src/prost/ and /// ../proto/src/tenderdash.rs -pub fn proto_compile() { +/// +/// # Arguments +/// +/// * `module_name` - name of module to put generated files into +pub fn proto_compile(module_name: &str) { let root = PathBuf::from(env!("CARGO_MANIFEST_DIR")); - let tenderdash_lib_target = root - .join("..") - .join("proto") - .join("src") - .join("tenderdash.rs"); - - let prost_out_dir = root.join("..").join("proto").join("src").join("prost"); + let prost_out_dir = root.join("..").join("proto").join("src").join(module_name); + let tenderdash_lib_target = prost_out_dir.join("mod.rs"); let out_dir = var("OUT_DIR") .map(PathBuf::from) @@ -52,7 +51,7 @@ pub fn proto_compile() { // check if this commitish is already downloaded let download = std::fs::metadata(tenderdash_dir.join("proto")).is_err() - || !check_state(&prost_out_dir, &commitish); + || !check_state(&prost_out_dir, &commitish, module_name); if download { println!("[info] => Fetching {TENDERDASH_REPO} at {commitish} into {tenderdash_dir:?}."); @@ -121,8 +120,14 @@ pub fn proto_compile() { println!("[info] => Removing old structs and copying new structs."); copy_files(&out_dir, &prost_out_dir); // This panics if it fails. - generate_tenderdash_lib(&out_dir, &tenderdash_lib_target, &abci_ver, &tenderdash_ver); + generate_tenderdash_lib( + &out_dir, + &tenderdash_lib_target, + &abci_ver, + &tenderdash_ver, + module_name, + ); - save_state(&prost_out_dir, &commitish); + save_state(&prost_out_dir, &commitish, module_name); println!("[info] => Done!"); } diff --git a/proto/build.rs b/proto/build.rs index 2087ba7..4a598d3 100644 --- a/proto/build.rs +++ b/proto/build.rs @@ -11,7 +11,10 @@ fn main() { env::set_var("TENDERDASH_COMMITISH", DEFAULT_VERSION); } - tenderdash_proto_compiler::proto_compile(); + #[cfg(feature = "std")] + tenderdash_proto_compiler::proto_compile("tenderdash_std"); + #[cfg(not(feature = "std"))] + tenderdash_proto_compiler::proto_compile("tenderdash_nostd"); println!("cargo:rerun-if-changed=../proto-compiler/src"); println!("cargo:rerun-if-changed=Cargo.toml"); diff --git a/proto/src/.gitignore b/proto/src/.gitignore index 3cc990e..2a145fb 100644 --- a/proto/src/.gitignore +++ b/proto/src/.gitignore @@ -1,2 +1,6 @@ +tenderdash_nostd/ +tenderdash_std/ + +# prost/ and tenderdash.rs are deprecated and can be removed in the future prost/ tenderdash.rs diff --git a/proto/src/lib.rs b/proto/src/lib.rs index ca3ad64..fee02dc 100644 --- a/proto/src/lib.rs +++ b/proto/src/lib.rs @@ -20,8 +20,6 @@ pub mod google { } mod error; -#[allow(warnings)] -mod tenderdash; #[cfg(not(feature = "std"))] use core::{ @@ -34,12 +32,22 @@ use std::fmt::Display; use bytes::{Buf, BufMut}; pub use error::Error; use prost::{encoding::encoded_len_varint, Message}; -pub use tenderdash::*; +#[cfg(not(feature = "std"))] +pub mod tenderdash_nostd; +#[allow(warnings)] +#[cfg(not(feature = "std"))] +pub use tenderdash_nostd::*; + +#[cfg(feature = "std")] +#[allow(warnings)] +pub mod tenderdash_std; +#[cfg(feature = "std")] +pub use tenderdash_std::*; pub mod serializers; +pub use meta::ABCI_VERSION; use prelude::*; -pub use tenderdash::meta::ABCI_VERSION; #[cfg(feature = "grpc")] pub use tonic;