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

Move out tendermint::config to tendermint-config crate #986

Merged
merged 19 commits into from
Oct 7, 2021
Merged
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
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

members = [
"abci",
"config",
"light-client",
"light-client-js",
"p2p",
Expand Down
2 changes: 1 addition & 1 deletion abci/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
//! have them interact. In practice, the client interaction will be performed
//! by a full Tendermint node.
//!
//! ```rust
//! ```ignore
soareschen marked this conversation as resolved.
Show resolved Hide resolved
//! use tendermint_abci::{KeyValueStoreApp, ServerBuilder, ClientBuilder};
//! use tendermint_proto::abci::{RequestEcho, RequestDeliverTx, RequestQuery};
//!
Expand Down
49 changes: 49 additions & 0 deletions config/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
[package]
name = "tendermint-config"
version = "0.21.0" # Also update `html_root_url` in lib.rs and
soareschen marked this conversation as resolved.
Show resolved Hide resolved
# depending crates (rpc, light-node, ..) when bumping this
license = "Apache-2.0"
homepage = "https://www.tendermint.com/"
repository = "https://github.com/informalsystems/tendermint-rs/tree/master/tendermint"
readme = "../README.md"
categories = ["cryptography", "cryptography::cryptocurrencies", "database"]
keywords = ["blockchain", "bft", "consensus", "cosmos", "tendermint"]
edition = "2018"

description = """
tendermint-config provides functions for loading and validating Tendermint
configuration files. It is moved out of the tendermint crate for no_std support
in the tendermint crate.
"""

authors = [
"Informal Systems <[email protected]>",
"Ismail Khoffi <[email protected]>",
"ValarDragon <[email protected]>",
"Tony Arcieri <[email protected]>",
soareschen marked this conversation as resolved.
Show resolved Hide resolved
]

[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]

[lib]
crate-type = ["cdylib", "rlib"]

[dependencies]
tendermint = { version = "0.21.0", default-features = false, path = "../tendermint" }
flex-error = { version = "0.4.1", default-features = false }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
toml = { version = "0.5" }
url = { version = "2.2" }

[dev-dependencies]
pretty_assertions = "0.7.2"

[features]
default = ["std", "eyre_tracer"]
eyre_tracer = ["flex-error/eyre_tracer"]
std = [
"flex-error/std"
]
9 changes: 4 additions & 5 deletions tendermint/src/config.rs → config/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,18 @@
//! - `node_key.rs`: `config::node_key::NodeKey`
//! - `priv_validator_key.rs`: `config::priv_validator_key::PrivValidatorKey`

mod node_key;
mod priv_validator_key;
use crate::net;
use crate::node_key::NodeKey;
use crate::Error;

pub use self::{node_key::NodeKey, priv_validator_key::PrivValidatorKey};

use crate::{error::Error, genesis::Genesis, net, node, Moniker, Timeout};
use serde::{de, de::Error as _, ser, Deserialize, Serialize};
use std::{
collections::BTreeMap,
fmt, fs,
path::{Path, PathBuf},
str::FromStr,
};
use tendermint::{genesis::Genesis, node, Moniker, Timeout};

/// Tendermint `config.toml` file
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
Expand Down
37 changes: 37 additions & 0 deletions config/src/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use flex_error::{define_error, DisplayOnly};
use std::io::Error as IoError;
use tendermint::Error as TendermintError;

define_error! {
#[derive(Debug, Clone, PartialEq, Eq)]
Error {
Io
[ DisplayOnly<IoError> ]
|_| { format_args!("I/O error") },

FileIo
{ path: String }
[ DisplayOnly<IoError> ]
|e| { format_args!("failed to open file: {}", e.path) },

Parse
{ data: String }
| e | { format_args!("error parsing data: {}", e.data) },

SerdeJson
[ DisplayOnly<serde_json::Error> ]
|_| { format_args!("serde json error") },

Toml
[ DisplayOnly<toml::de::Error> ]
|_| { format_args!("toml de error") },

ParseUrl
[ DisplayOnly<url::ParseError> ]
|_| { format_args!("error parsing url error") },

Tendermint
[ TendermintError ]
|_| { format_args!("tendermint error") },
}
}
27 changes: 27 additions & 0 deletions config/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//! Tendermint Configuration Utilities
//!
//! This crate defines the [`TendermintConfig`] type, which is used by
//! crates such as `tendermint-rpc` to perform operations based on
//! a common configuration type.

#![cfg_attr(docsrs, feature(doc_cfg))]
#![deny(
warnings,
trivial_casts,
trivial_numeric_casts,
unused_import_braces,
unused_qualifications
)]
#![forbid(unsafe_code)]

pub mod net;

mod config;
mod error;
mod node_key;
mod priv_validator_key;

pub use config::*;
pub use error::*;
pub use node_key::NodeKey;
pub use priv_validator_key::PrivValidatorKey;
30 changes: 22 additions & 8 deletions tendermint/src/net.rs → config/src/net.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
//! Remote addresses (`tcp://` or `unix://`)

use crate::{error::Error, node};
use crate::error::Error;

use serde::{de::Error as _, Deserialize, Deserializer, Serialize, Serializer};
use std::{
fmt::{self, Display},
path::PathBuf,
str::{self, FromStr},
};
use tendermint::node::{self, info::ListenAddress};
use url::Url;

/// URI prefix for TCP connections
Expand Down Expand Up @@ -40,10 +40,23 @@ pub enum Address {
/// UNIX domain sockets
Unix {
/// Path to a UNIX domain socket path
path: PathBuf,
path: String,
},
}

impl Address {
/// Convert `ListenAddress` to a `net::Address`
pub fn from_listen_address(address: &ListenAddress) -> Option<Self> {
let raw_address = address.as_str();
// TODO(tarcieri): validate these and handle them better at parse time
if raw_address.starts_with("tcp://") {
raw_address.parse().ok()
} else {
format!("tcp://{}", raw_address).parse().ok()
}
}
}

impl<'de> Deserialize<'de> for Address {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
Self::from_str(&String::deserialize(deserializer)?)
Expand All @@ -64,7 +77,7 @@ impl Display for Address {
host,
port,
} => write!(f, "{}{}@{}:{}", TCP_PREFIX, peer_id, host, port),
Address::Unix { path } => write!(f, "{}{}", UNIX_PREFIX, path.display()),
Address::Unix { path } => write!(f, "{}{}", UNIX_PREFIX, path),
}
}
}
Expand All @@ -83,7 +96,8 @@ impl FromStr for Address {
match url.scheme() {
"tcp" => Ok(Self::Tcp {
peer_id: if !url.username().is_empty() {
Some(url.username().parse()?)
let username = url.username().parse().map_err(Error::tendermint)?;
soareschen marked this conversation as resolved.
Show resolved Hide resolved
Some(username)
} else {
None
},
Expand All @@ -98,7 +112,7 @@ impl FromStr for Address {
})?,
}),
"unix" => Ok(Self::Unix {
path: PathBuf::from(url.path()),
path: url.path().to_string(),
}),
_ => Err(Error::parse(format!("invalid address scheme: {:?}", addr))),
}
Expand All @@ -114,7 +128,7 @@ impl Serialize for Address {
#[cfg(test)]
mod tests {
use super::*;
use crate::node;
use tendermint::node;

const EXAMPLE_TCP_ADDR: &str =
"tcp://[email protected]:26656";
Expand Down Expand Up @@ -175,7 +189,7 @@ mod tests {
let addr = EXAMPLE_UNIX_ADDR.parse::<Address>().unwrap();
match addr {
Address::Unix { path } => {
assert_eq!(path.to_str().unwrap(), "/tmp/node.sock");
assert_eq!(path, "/tmp/node.sock");
}
other => panic!("unexpected address type: {:?}", other),
}
Expand Down
5 changes: 4 additions & 1 deletion tendermint/src/config/node_key.rs → config/src/node_key.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
//! Node keys

use crate::{error::Error, node, private_key::PrivateKey, public_key::PublicKey};
use serde::{Deserialize, Serialize};
use std::{fs, path::Path};
use tendermint::{node, private_key::PrivateKey, public_key::PublicKey};

use crate::error::Error;

/// P2P node private keys
#[derive(Serialize, Deserialize)]
Expand Down Expand Up @@ -33,6 +35,7 @@ impl NodeKey {
pub fn public_key(&self) -> PublicKey {
match &self.priv_key {
PrivateKey::Ed25519(keypair) => keypair.public.into(),
_ => todo!(),
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
//! Validator private keys

use crate::public_key::TendermintKey;
use crate::{account, error::Error, private_key::PrivateKey, public_key::PublicKey};
use serde::{Deserialize, Serialize};
use std::{fs, path::Path};
use tendermint::public_key::TendermintKey;
use tendermint::{account, private_key::PrivateKey, public_key::PublicKey};

use crate::error::Error;

/// Validator private key
#[derive(Serialize, Deserialize)] // JSON custom serialization for priv_validator_key.json
Expand All @@ -25,7 +27,8 @@ impl PrivValidatorKey {
serde_json::from_str::<Self>(json_string.as_ref()).map_err(Error::serde_json)?;

// Validate that the parsed key type is usable as a consensus key
TendermintKey::new_consensus_key(result.priv_key.public_key())?;
TendermintKey::new_consensus_key(result.priv_key.public_key())
.map_err(Error::tendermint)?;
soareschen marked this conversation as resolved.
Show resolved Hide resolved

Ok(result)
}
Expand Down
3 changes: 2 additions & 1 deletion tendermint/tests/config.rs → config/tests/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ mod files {
#[cfg(test)]
use pretty_assertions::assert_eq;
use std::{fs, path::PathBuf, time::Duration};
use tendermint::{config::*, net, node};
use tendermint::node;
use tendermint_config::*;

/// Read a fixture file from the `support/config` directory
fn read_fixture(name: &str) -> String {
Expand Down
Loading