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

Add TLS support for the Light Client #842

Merged
merged 24 commits into from
Mar 29, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
5f57f97
Remove unused file
thanethomson Mar 24, 2021
e02b109
Refactor validators RPC endpoint interface
thanethomson Mar 24, 2021
c8e62b2
Merge latest changes from master
thanethomson Mar 24, 2021
2baf2d6
Ensure "total" response field is a string
thanethomson Mar 24, 2021
88e2d9c
Add serializer for optional types that need to be converted to/from a…
thanethomson Mar 25, 2021
45b9acd
Refactor to ensure page numbers and per-page values are converted to/…
thanethomson Mar 25, 2021
f0c26f7
Convert tcp:// scheme to http:// for RPC addresses
thanethomson Mar 25, 2021
14ad69f
Add Light Client support for RPC URLs instead of net::Address
thanethomson Mar 25, 2021
fa07173
Revert 14ad69f for now
thanethomson Mar 25, 2021
d0ba5bc
Revert f0c26f7
thanethomson Mar 25, 2021
f21f3ac
Merge latest changes from master
thanethomson Mar 25, 2021
4c251c5
Add CHANGELOG
thanethomson Mar 25, 2021
856ff0b
Convert tcp:// scheme to http:// for RPC addresses
thanethomson Mar 25, 2021
067e06a
Add Light Client support for RPC URLs instead of net::Address
thanethomson Mar 25, 2021
05c53e8
Comment not needed
thanethomson Mar 25, 2021
3196081
Expose rpc::Url type
thanethomson Mar 25, 2021
48aced5
Update kvstore integration test to use rpc::Url
thanethomson Mar 26, 2021
a106505
Update CHANGELOG
thanethomson Mar 26, 2021
35f9bff
Remove debug output from height log
thanethomson Mar 26, 2021
ff81071
Merge CI changes from master
thanethomson Mar 26, 2021
62830cc
Merge latest CI changes from master
thanethomson Mar 26, 2021
9fe5e75
Resolve conflicts with master
thanethomson Mar 29, 2021
90fb573
Attach serialization directly to tendermint_rpc::Url
thanethomson Mar 29, 2021
499100a
Add some happy path tests for tendermint_rpc::Url parsing
thanethomson Mar 29, 2021
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
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@
* `[tendermint]` The `tendermint::block::CommitSig` enum's members have been
renamed to be consistent with Rust's naming conventions. For example,
`BlockIDFlagAbsent` is now renamed to `BlockIdFlagAbsent` ([#839])
* `[tendermint-light-client]` The Light Client no longer uses
`tendermint::net::Address` to refer to peers, and instead uses the
`tendermint_rpc::Url` type ([#835])
* `[tendermint-rpc]` The `Client::validators` method now requires a `Paging`
parameter. Previously, this wasn't possible and, if the network had more than
30 validators (the default for the RPC endpoint), it only returned a subset
of the validators ([#831])
* `[tendermint-rpc]` The `Client::validators` method now requires a `Paging`
parameter. Previously, this wasn't possible and, if the network had more than
30 validators (the default for the RPC endpoint), it only returned a subset
Expand All @@ -27,6 +34,8 @@

* `[tendermint-abci]` Release minimal framework for building ABCI applications
in Rust ([#794])
* `[tendermint-light-client]` The Light Client now provides support for secure
(HTTPS) connections to nodes ([#835])
* `[tendermint-light-client-js]` First release of the
`tendermint-light-client-js` crate to provide access to Tendermint Light
Client functionality from WASM. This only provides access to the `verify`
Expand All @@ -50,6 +59,7 @@
[#812]: https://github.com/informalsystems/tendermint-rs/pull/812
[#820]: https://github.com/informalsystems/tendermint-rs/pull/820
[#831]: https://github.com/informalsystems/tendermint-rs/issues/831
[#835]: https://github.com/informalsystems/tendermint-rs/issues/835
[#839]: https://github.com/informalsystems/tendermint-rs/pull/839

## v0.18.1
Expand Down
4 changes: 2 additions & 2 deletions light-client/examples/light_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ struct SyncOpts {
meta = "ADDR",
default = "tcp://127.0.0.1:26657"
)]
address: tendermint::net::Address,
address: tendermint_rpc::Url,
#[options(
help = "height of the initial trusted state (optional if store already initialized)",
meta = "HEIGHT"
Expand Down Expand Up @@ -81,7 +81,7 @@ fn main() {

fn make_instance(
peer_id: PeerId,
addr: tendermint::net::Address,
addr: tendermint_rpc::Url,
db_path: impl AsRef<Path>,
opts: &SyncOpts,
) -> Result<Instance, BoxError> {
Expand Down
12 changes: 5 additions & 7 deletions light-client/src/builder/supervisor.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
use std::time::Duration;

use tendermint::net;

use crate::builder::error::{self, Error};
use crate::peer_list::{PeerList, PeerListBuilder};
use crate::supervisor::Instance;
Expand All @@ -21,7 +19,7 @@ pub struct Done;
#[must_use]
pub struct SupervisorBuilder<State> {
instances: PeerListBuilder<Instance>,
addresses: PeerListBuilder<net::Address>,
addresses: PeerListBuilder<tendermint_rpc::Url>,
evidence_reporting_timeout: Option<Duration>,
#[allow(dead_code)]
state: State,
Expand Down Expand Up @@ -66,7 +64,7 @@ impl SupervisorBuilder<Init> {
pub fn primary(
mut self,
peer_id: PeerId,
address: net::Address,
address: tendermint_rpc::Url,
instance: Instance,
) -> SupervisorBuilder<HasPrimary> {
self.instances.primary(peer_id, instance);
Expand All @@ -81,7 +79,7 @@ impl SupervisorBuilder<HasPrimary> {
pub fn witness(
mut self,
peer_id: PeerId,
address: net::Address,
address: tendermint_rpc::Url,
instance: Instance,
) -> SupervisorBuilder<Done> {
self.instances.witness(peer_id, instance);
Expand All @@ -93,7 +91,7 @@ impl SupervisorBuilder<HasPrimary> {
/// Add multiple witnesses at once.
pub fn witnesses(
mut self,
witnesses: impl IntoIterator<Item = (PeerId, net::Address, Instance)>,
witnesses: impl IntoIterator<Item = (PeerId, tendermint_rpc::Url, Instance)>,
) -> Result<SupervisorBuilder<Done>, Error> {
let mut iter = witnesses.into_iter().peekable();
if iter.peek().is_none() {
Expand Down Expand Up @@ -126,7 +124,7 @@ impl SupervisorBuilder<Done> {

/// Get the underlying list of instances and addresses.
#[must_use]
pub fn inner(self) -> (PeerList<Instance>, PeerList<net::Address>) {
pub fn inner(self) -> (PeerList<Instance>, PeerList<tendermint_rpc::Url>) {
(self.instances.build(), self.addresses.build())
}
}
4 changes: 2 additions & 2 deletions light-client/src/evidence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ mod prod {
/// nodes via RPC.
#[derive(Clone, Debug)]
pub struct ProdEvidenceReporter {
peer_map: HashMap<PeerId, tendermint::net::Address>,
peer_map: HashMap<PeerId, tendermint_rpc::Url>,
timeout: Option<Duration>,
}

Expand All @@ -61,7 +61,7 @@ mod prod {
///
/// A peer map which maps peer IDS to their network address must be supplied.
pub fn new(
peer_map: HashMap<PeerId, tendermint::net::Address>,
peer_map: HashMap<PeerId, tendermint_rpc::Url>,
timeout: Option<Duration>,
) -> Self {
Self { peer_map, timeout }
Expand Down
2 changes: 1 addition & 1 deletion light-client/src/supervisor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ impl std::fmt::Debug for Supervisor {
static_assertions::assert_impl_all!(Supervisor: Send);

impl Supervisor {
/// Constructs a new supevisor from the given list of peers and fork detector instance.
/// Constructs a new supervisor from the given list of peers and fork detector instance.
pub fn new(
peers: PeerList<Instance>,
fork_detector: impl ForkDetector + 'static,
Expand Down
1 change: 1 addition & 0 deletions light-node/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ thiserror = "1.0"

tendermint = { version = "0.18.1", path = "../tendermint" }
tendermint-light-client = { version = "0.18.1", path = "../light-client", features = ["lightstore-sled"] }
tendermint-proto = { version = "0.18.1", path = "../proto" }
tendermint-rpc = { version = "0.18.1", path = "../rpc", features = ["http-client"] }

[dependencies.abscissa_core]
Expand Down
30 changes: 23 additions & 7 deletions light-node/src/commands/initialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,9 @@ use std::ops::Deref;
use std::time::Duration;

use crate::application::app_config;
use crate::config::LightClientConfig;
use crate::config::LightNodeConfig;
use crate::config::{LightClientConfig, LightNodeConfig};

use abscissa_core::status_err;
use abscissa_core::status_warn;
use abscissa_core::Command;
use abscissa_core::Options;
use abscissa_core::Runnable;
use abscissa_core::{status_err, status_info, status_warn, Command, Options, Runnable};

use tendermint::{hash, Hash};

Expand Down Expand Up @@ -57,6 +52,8 @@ impl Runnable for InitCmd {
) {
status_err!("failed to initialize light client: {}", e);
// TODO: Set exit code to 1
} else {
status_info!("init", "done");
}
}
}
Expand All @@ -68,6 +65,20 @@ fn initialize_subjectively(
config: &LightClientConfig,
timeout: Option<Duration>,
) -> Result<Instance, String> {
status_info!(
"init",
"starting subjective initialization for height: {}",
height,
);
status_info!("init", "subjective header hash: {}", subjective_header_hash,);
status_info!(
"init",
"using sled store located at: {}",
config
.db_path
.to_str()
.ok_or("unable to obtain sled db path")?
);
let light_store =
SledStore::open(&config.db_path).map_err(|e| format!("could not open database: {}", e))?;

Expand All @@ -79,6 +90,11 @@ fn initialize_subjectively(
);
}

status_info!(
"init",
"Tendermint RPC address: {}",
config.address.to_string()
);
let rpc_client = rpc::HttpClient::new(config.address.clone()).map_err(|e| e.to_string())?;

let builder = LightClientBuilder::prod(
Expand Down
30 changes: 23 additions & 7 deletions light-node/src/commands/start.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,8 @@ use crate::config::{LightClientConfig, LightNodeConfig};
use crate::rpc;
use crate::rpc::Server;

use abscissa_core::config;
use abscissa_core::path::PathBuf;
use abscissa_core::status_err;
use abscissa_core::status_info;
use abscissa_core::Command;
use abscissa_core::FrameworkError;
use abscissa_core::Options;
use abscissa_core::Runnable;
use abscissa_core::{config, status_err, status_info, Command, FrameworkError, Options, Runnable};

use std::net::SocketAddr;
use std::ops::Deref;
Expand Down Expand Up @@ -125,12 +119,27 @@ impl StartCmd {
options: light_client::Options,
timeout: Option<Duration>,
) -> Result<Instance, String> {
status_info!(
"start",
"constructing Light Client for peer {}",
light_config.peer_id.to_string()
);
status_info!("start", "RPC address: {}", light_config.address.to_string());
let rpc_client = tendermint_rpc::HttpClient::new(light_config.address.clone())
.map_err(|e| format!("failed to create HTTP client: {}", e))?;

let light_store = SledStore::open(&light_config.db_path)
.map_err(|e| format!("could not open database: {}", e))?;

status_info!(
"start",
"highest trusted or verified height: {}",
light_store
.highest_trusted_or_verified()
.map(|b| b.signed_header.header.height.to_string())
.unwrap_or_else(|| "(none)".to_owned()),
);

let builder = LightClientBuilder::prod(
light_config.peer_id,
rpc_client,
Expand Down Expand Up @@ -161,6 +170,12 @@ impl StartCmd {

let builder = SupervisorBuilder::new();

status_info!(
"start",
"primary: {} @ {}",
primary_conf.peer_id,
primary_conf.address
);
let primary_instance = self.make_instance(primary_conf, options, Some(timeout))?;
let builder = builder.primary(
primary_conf.peer_id,
Expand All @@ -173,6 +188,7 @@ impl StartCmd {
let instance = self.make_instance(witness_conf, options, Some(timeout))?;
witnesses.push((witness_conf.peer_id, witness_conf.address.clone(), instance));
}
status_info!("start", "{} witness(es)", witnesses.len());

let builder = builder
.witnesses(witnesses)
Expand Down
2 changes: 1 addition & 1 deletion light-node/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ pub struct LightNodeConfig {
pub struct LightClientConfig {
/// Address of the Tendermint fullnode to connect to and
/// fetch LightBlock data from.
pub address: tendermint::net::Address,
pub address: tendermint_rpc::Url,
/// PeerID of the same Tendermint fullnode.
pub peer_id: PeerId,
/// The data base folder for this instance's store.
Expand Down
11 changes: 6 additions & 5 deletions rpc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,7 @@ http-client = [
"hyper-rustls",
"tokio/fs",
"tokio/macros",
"tracing",
"url"
"tracing"
]
secp256k1 = [ "tendermint/secp256k1" ]
websocket-client = [
Expand All @@ -58,8 +57,7 @@ websocket-client = [
"tokio/macros",
"tokio/sync",
"tokio/time",
"tracing",
"url"
"tracing"
]

[dependencies]
Expand All @@ -78,6 +76,7 @@ tendermint-proto = { version = "0.18.1", path = "../proto" }
thiserror = "1"
uuid = { version = "0.8", default-features = false }
subtle-encoding = { version = "0.5", features = ["bech32-preview"] }
url = "2.2"
walkdir = "2.3"

async-trait = { version = "0.1", optional = true }
Expand All @@ -91,4 +90,6 @@ structopt = { version = "0.3", optional = true }
tokio = { version = "1.0", optional = true }
tracing = { version = "0.1", optional = true }
tracing-subscriber = { version = "0.2", optional = true }
url = { version = "2.2", optional = true }

[dev-dependencies]
lazy_static = "1.4.0"
2 changes: 2 additions & 0 deletions rpc/src/endpoint/validators.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ pub const DEFAULT_VALIDATORS_PER_PAGE: u8 = 30;

/// List validators for a specific block
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[non_exhaustive]
pub struct Request {
/// The height at which to retrieve the validator set. If not specified,
/// defaults to the latest height.
Expand Down Expand Up @@ -65,6 +66,7 @@ impl crate::SimpleRequest for Request {}

/// Validator responses
#[derive(Clone, Debug, Deserialize, Serialize)]
#[non_exhaustive]
pub struct Response {
/// Block height
pub block_height: block::Height,
Expand Down
1 change: 0 additions & 1 deletion rpc/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,6 @@ impl From<std::io::Error> for Error {
}
}

#[cfg(any(feature = "http-client", feature = "websocket-client"))]
impl From<url::ParseError> for Error {
fn from(e: url::ParseError) -> Self {
Error::invalid_params(&e.to_string())
Expand Down
20 changes: 11 additions & 9 deletions rpc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,10 @@
#[cfg(any(feature = "http-client", feature = "websocket-client"))]
mod client;
#[cfg(any(feature = "http-client", feature = "websocket-client"))]
mod rpc_url;
#[cfg(any(feature = "http-client", feature = "websocket-client"))]
pub use client::{
Client, MockClient, MockRequestMatcher, MockRequestMethodMatcher, Subscription,
SubscriptionClient,
};
#[cfg(any(feature = "http-client", feature = "websocket-client"))]
pub use rpc_url::{Scheme, Url};

#[cfg(feature = "http-client")]
pub use client::{HttpClient, HttpClientUrl};
Expand All @@ -55,11 +51,17 @@ pub mod query;
pub mod request;
pub mod response;
mod result;
mod rpc_url;
mod utils;
mod version;

pub use self::{
error::Error, id::Id, method::Method, order::Order, paging::PageNumber, paging::Paging,
paging::PerPage, request::Request, request::SimpleRequest, response::Response, result::Result,
version::Version,
};
pub use error::Error;
pub use id::Id;
pub use method::Method;
pub use order::Order;
pub use paging::{PageNumber, Paging, PerPage};
pub use request::{Request, SimpleRequest};
pub use response::Response;
pub use result::Result;
pub use rpc_url::{Scheme, Url};
pub use version::Version;
Loading