From 14ad69f02839dabd7c8937d2ba885f0aa2783f94 Mon Sep 17 00:00:00 2001 From: Thane Thomson Date: Thu, 25 Mar 2021 07:42:42 -0400 Subject: [PATCH] Add Light Client support for RPC URLs instead of net::Address Signed-off-by: Thane Thomson --- light-client/examples/light_client.rs | 4 ++-- light-client/src/builder/supervisor.rs | 12 +++++------ light-client/src/evidence.rs | 4 ++-- light-client/src/supervisor.rs | 2 +- light-node/Cargo.toml | 1 + light-node/src/commands/initialize.rs | 30 ++++++++++++++++++++------ light-node/src/commands/start.rs | 29 +++++++++++++++++++------ light-node/src/config.rs | 3 ++- 8 files changed, 58 insertions(+), 27 deletions(-) diff --git a/light-client/examples/light_client.rs b/light-client/examples/light_client.rs index dc14fcd66..9c3b7ce36 100644 --- a/light-client/examples/light_client.rs +++ b/light-client/examples/light_client.rs @@ -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" @@ -81,7 +81,7 @@ fn main() { fn make_instance( peer_id: PeerId, - addr: tendermint::net::Address, + addr: tendermint_rpc::Url, db_path: impl AsRef, opts: &SyncOpts, ) -> Result { diff --git a/light-client/src/builder/supervisor.rs b/light-client/src/builder/supervisor.rs index 18469f682..0cb8ba647 100644 --- a/light-client/src/builder/supervisor.rs +++ b/light-client/src/builder/supervisor.rs @@ -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; @@ -21,7 +19,7 @@ pub struct Done; #[must_use] pub struct SupervisorBuilder { instances: PeerListBuilder, - addresses: PeerListBuilder, + addresses: PeerListBuilder, evidence_reporting_timeout: Option, #[allow(dead_code)] state: State, @@ -66,7 +64,7 @@ impl SupervisorBuilder { pub fn primary( mut self, peer_id: PeerId, - address: net::Address, + address: tendermint_rpc::Url, instance: Instance, ) -> SupervisorBuilder { self.instances.primary(peer_id, instance); @@ -81,7 +79,7 @@ impl SupervisorBuilder { pub fn witness( mut self, peer_id: PeerId, - address: net::Address, + address: tendermint_rpc::Url, instance: Instance, ) -> SupervisorBuilder { self.instances.witness(peer_id, instance); @@ -93,7 +91,7 @@ impl SupervisorBuilder { /// Add multiple witnesses at once. pub fn witnesses( mut self, - witnesses: impl IntoIterator, + witnesses: impl IntoIterator, ) -> Result, Error> { let mut iter = witnesses.into_iter().peekable(); if iter.peek().is_none() { @@ -126,7 +124,7 @@ impl SupervisorBuilder { /// Get the underlying list of instances and addresses. #[must_use] - pub fn inner(self) -> (PeerList, PeerList) { + pub fn inner(self) -> (PeerList, PeerList) { (self.instances.build(), self.addresses.build()) } } diff --git a/light-client/src/evidence.rs b/light-client/src/evidence.rs index d18b10c7e..2bfd7c411 100644 --- a/light-client/src/evidence.rs +++ b/light-client/src/evidence.rs @@ -34,7 +34,7 @@ mod prod { /// nodes via RPC. #[derive(Clone, Debug)] pub struct ProdEvidenceReporter { - peer_map: HashMap, + peer_map: HashMap, timeout: Option, } @@ -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, + peer_map: HashMap, timeout: Option, ) -> Self { Self { peer_map, timeout } diff --git a/light-client/src/supervisor.rs b/light-client/src/supervisor.rs index be5749771..f4c72d59e 100644 --- a/light-client/src/supervisor.rs +++ b/light-client/src/supervisor.rs @@ -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, fork_detector: impl ForkDetector + 'static, diff --git a/light-node/Cargo.toml b/light-node/Cargo.toml index 18a1b8b3c..29dbe1474 100644 --- a/light-node/Cargo.toml +++ b/light-node/Cargo.toml @@ -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] diff --git a/light-node/src/commands/initialize.rs b/light-node/src/commands/initialize.rs index b1013b288..1895ff81e 100644 --- a/light-node/src/commands/initialize.rs +++ b/light-node/src/commands/initialize.rs @@ -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}; @@ -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"); } } } @@ -68,6 +65,20 @@ fn initialize_subjectively( config: &LightClientConfig, timeout: Option, ) -> Result { + 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))?; @@ -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( diff --git a/light-node/src/commands/start.rs b/light-node/src/commands/start.rs index dcde6e008..a8bd89add 100644 --- a/light-node/src/commands/start.rs +++ b/light-node/src/commands/start.rs @@ -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; @@ -125,12 +119,26 @@ impl StartCmd { options: light_client::Options, timeout: Option, ) -> Result { + 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), + ); + let builder = LightClientBuilder::prod( light_config.peer_id, rpc_client, @@ -161,6 +169,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, @@ -173,6 +187,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) diff --git a/light-node/src/config.rs b/light-node/src/config.rs index bf2ac1944..df6344547 100644 --- a/light-node/src/config.rs +++ b/light-node/src/config.rs @@ -41,7 +41,8 @@ pub struct LightNodeConfig { pub struct LightClientConfig { /// Address of the Tendermint fullnode to connect to and /// fetch LightBlock data from. - pub address: tendermint::net::Address, + #[serde(with = "tendermint_proto::serializers::from_str")] + pub address: tendermint_rpc::Url, /// PeerID of the same Tendermint fullnode. pub peer_id: PeerId, /// The data base folder for this instance's store.