From 02f1bc56575d2874e62dcab5cabf5a040f35b527 Mon Sep 17 00:00:00 2001 From: Ismail Khoffi Date: Wed, 15 Jul 2020 22:10:33 +0200 Subject: [PATCH 01/15] WIP: add `LatestStatus` type and a method to the handler --- light-client/src/supervisor.rs | 37 +++++++++++++++++++++++++++++++- light-client/src/types.rs | 22 +++++++++++++++++++ light-node/src/commands/start.rs | 3 +-- 3 files changed, 59 insertions(+), 3 deletions(-) diff --git a/light-client/src/supervisor.rs b/light-client/src/supervisor.rs index 3f0cffdb0..8a5394a0d 100644 --- a/light-client/src/supervisor.rs +++ b/light-client/src/supervisor.rs @@ -9,7 +9,8 @@ use crate::fork_detector::{Fork, ForkDetection, ForkDetector}; use crate::light_client::LightClient; use crate::peer_list::PeerList; use crate::state::State; -use crate::types::{Height, LightBlock, PeerId, Status}; +use crate::types::{Height, LightBlock, PeerId, Status, LatestStatus}; +use tendermint::lite::{Header, ValidatorSet}; pub trait Handle { /// Get latest trusted block from the [`Supervisor`]. @@ -17,6 +18,10 @@ pub trait Handle { todo!() } + fn latest_status(&self) -> Result, Error> { + todo!() + } + /// Verify to the highest block. fn verify_to_highest(&self) -> Result { todo!() @@ -45,6 +50,8 @@ enum HandleInput { VerifyToTarget(Height, channel::Sender>), /// Get the latest trusted block. LatestTrusted(channel::Sender>), + /// Get the current status of the LightClient + GetStatus(channel::Sender>) } /// A light client `Instance` packages a `LightClient` together with its `State`. @@ -166,6 +173,22 @@ impl Supervisor { self.verify(None) } + /// Return latest trusted status summary. + fn latest_status(&mut self) -> Option { + let latest_trusted = self.peers.primary().latest_trusted(); + match latest_trusted { + Some(trusted) => { + let connected_nodes: Vec = Vec::new(); + Some(LatestStatus::new( + trusted.signed_header.header.height(), + trusted.signed_header.header.hash(), + trusted.next_validators.hash(), + connected_nodes, + ))}, + None => None, + } + } + /// Verify to the block at the given height. pub fn verify_to_target(&mut self, height: Height) -> Result { self.verify(Some(height)) @@ -322,6 +345,10 @@ impl Supervisor { let outcome = self.verify_to_highest(); sender.send(outcome).map_err(ErrorKind::from)?; } + HandleInput::GetStatus(sender) => { + let outcome = self.latest_status(); + sender.send(outcome).map_err(ErrorKind::from)?; + } } } } @@ -363,6 +390,14 @@ impl Handle for SupervisorHandle { Ok(receiver.recv().map_err(ErrorKind::from)?) } + fn latest_status(&self) -> Result, Error> { + let (sender, receiver) = channel::bounded::>(1); + self.sender + .send(HandleInput::GetStatus(sender)) + .map_err(ErrorKind::from)?; + Ok(receiver.recv().map_err(ErrorKind::from)?) + } + fn verify_to_highest(&self) -> Result { self.verify(HandleInput::VerifyToHighest) } diff --git a/light-client/src/types.rs b/light-client/src/types.rs index 5794ec9c2..654b25a6d 100644 --- a/light-client/src/types.rs +++ b/light-client/src/types.rs @@ -116,6 +116,28 @@ impl LightBlock { } } +/// Contains the local status information, like the latest height, latest block and valset hashes, +/// list of of connected full nodes (primary and witnesses). +#[derive(Clone, Debug, Display, PartialEq, Serialize, Deserialize)] +#[display(fmt = "{:?}", self)] +pub struct LatestStatus { + /// The latest height we are trusting. + pub height: Height, + /// The latest block hash we are trusting. + pub block_hash: Hash, + /// The latest validator set we are trusting. + /// Note that this potentially did not yet sign a header yet. + pub valset_hash: Hash, + /// The list of fullnodes we are connected to, primary and witnesses. + pub connected_nodes: Vec, +} + +impl LatestStatus { + pub fn new(height: u64, block_hash: Hash, valset_hash: Hash, connected_nodes: Vec) -> Self { + LatestStatus { height, block_hash, valset_hash, connected_nodes } + } +} + #[cfg(test)] mod tests { diff --git a/light-node/src/commands/start.rs b/light-node/src/commands/start.rs index bc85d5578..a9d0e318c 100644 --- a/light-node/src/commands/start.rs +++ b/light-node/src/commands/start.rs @@ -35,7 +35,6 @@ use tendermint_light_client::store::sled::SledStore; use tendermint_light_client::store::LightStore; use tendermint_light_client::supervisor::Handle; use tendermint_light_client::supervisor::{Instance, Supervisor}; -use tendermint_light_client::types::Status; /// `start` subcommand /// @@ -189,7 +188,7 @@ impl StartCmd { Supervisor::new( peer_list, ProdForkDetector::default(), - ProdEvidenceReporter::new(peer_map.clone()), + ProdEvidenceReporter::new(peer_map), ) } } From 3dee0ac9ba8798a9703c76f70007ed8ee9464162 Mon Sep 17 00:00:00 2001 From: Ismail Khoffi Date: Wed, 15 Jul 2020 22:13:54 +0200 Subject: [PATCH 02/15] add `LatestStatus` type and a method to the handler/supervisor and an RPC endpoint --- light-client/src/supervisor.rs | 7 ++++--- light-client/src/types.rs | 14 ++++++++++++-- light-node/src/rpc.rs | 16 ++++++++++++++++ 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/light-client/src/supervisor.rs b/light-client/src/supervisor.rs index 8a5394a0d..9ee11235a 100644 --- a/light-client/src/supervisor.rs +++ b/light-client/src/supervisor.rs @@ -9,7 +9,7 @@ use crate::fork_detector::{Fork, ForkDetection, ForkDetector}; use crate::light_client::LightClient; use crate::peer_list::PeerList; use crate::state::State; -use crate::types::{Height, LightBlock, PeerId, Status, LatestStatus}; +use crate::types::{Height, LatestStatus, LightBlock, PeerId, Status}; use tendermint::lite::{Header, ValidatorSet}; pub trait Handle { @@ -51,7 +51,7 @@ enum HandleInput { /// Get the latest trusted block. LatestTrusted(channel::Sender>), /// Get the current status of the LightClient - GetStatus(channel::Sender>) + GetStatus(channel::Sender>), } /// A light client `Instance` packages a `LightClient` together with its `State`. @@ -184,7 +184,8 @@ impl Supervisor { trusted.signed_header.header.hash(), trusted.next_validators.hash(), connected_nodes, - ))}, + )) + } None => None, } } diff --git a/light-client/src/types.rs b/light-client/src/types.rs index 654b25a6d..3d06df8bd 100644 --- a/light-client/src/types.rs +++ b/light-client/src/types.rs @@ -133,8 +133,18 @@ pub struct LatestStatus { } impl LatestStatus { - pub fn new(height: u64, block_hash: Hash, valset_hash: Hash, connected_nodes: Vec) -> Self { - LatestStatus { height, block_hash, valset_hash, connected_nodes } + pub fn new( + height: u64, + block_hash: Hash, + valset_hash: Hash, + connected_nodes: Vec, + ) -> Self { + LatestStatus { + height, + block_hash, + valset_hash, + connected_nodes, + } } } diff --git a/light-node/src/rpc.rs b/light-node/src/rpc.rs index f6b190fe2..6427b2e5c 100644 --- a/light-node/src/rpc.rs +++ b/light-node/src/rpc.rs @@ -38,6 +38,7 @@ mod sealed { use jsonrpc_derive::rpc; use tendermint_light_client::supervisor::Handle; + use tendermint_light_client::types::LatestStatus; use tendermint_light_client::types::LightBlock; #[rpc] @@ -45,6 +46,10 @@ mod sealed { /// Returns the latest trusted block. #[rpc(name = "state")] fn state(&self) -> FutureResult, Error>; + + /// Returns the latest status. + #[rpc(name = "status")] + fn status(&self) -> FutureResult, Error>; } pub use self::rpc_impl_Rpc::gen_client::Client; @@ -79,6 +84,17 @@ mod sealed { future::result(res) } + + fn status(&self) -> FutureResult, Error> { + let res = self.handle.latest_status().map_err(|e| { + let mut err = Error::internal_error(); + err.message = e.to_string(); + err.data = serde_json::to_value(e.kind()).ok(); + err + }); + + future::result(res) + } } } From 85d14f3f0d7b778147e3a0704c8502cb5de2a2cf Mon Sep 17 00:00:00 2001 From: Ismail Khoffi Date: Wed, 15 Jul 2020 22:44:14 +0200 Subject: [PATCH 03/15] Actually add the connected nodes --- light-client/src/supervisor.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/light-client/src/supervisor.rs b/light-client/src/supervisor.rs index 9ee11235a..a19c06079 100644 --- a/light-client/src/supervisor.rs +++ b/light-client/src/supervisor.rs @@ -178,7 +178,9 @@ impl Supervisor { let latest_trusted = self.peers.primary().latest_trusted(); match latest_trusted { Some(trusted) => { - let connected_nodes: Vec = Vec::new(); + let mut connected_nodes: Vec = Vec::new(); + connected_nodes.push(self.peers.primary_id()); + connected_nodes.append(&mut self.peers.witnesses_ids().iter().copied().collect()); Some(LatestStatus::new( trusted.signed_header.header.height(), trusted.signed_header.header.hash(), From d4f34899834333537433eef3640a9549731d6602 Mon Sep 17 00:00:00 2001 From: Ismail Khoffi Date: Thu, 16 Jul 2020 11:10:21 +0200 Subject: [PATCH 04/15] Add info output and fix main output - from `synced to block {} 1234` to `synced to block: 1234` --- light-node/src/commands/start.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/light-node/src/commands/start.rs b/light-node/src/commands/start.rs index a9d0e318c..434bca908 100644 --- a/light-node/src/commands/start.rs +++ b/light-node/src/commands/start.rs @@ -69,7 +69,7 @@ impl Runnable for StartCmd { loop { match handle.verify_to_highest() { Ok(light_block) => { - status_info!("synced to block {}", light_block.height().to_string()); + status_info!("synced to block:", light_block.height().to_string()); } Err(err) => { status_err!("sync failed: {}", err); @@ -156,6 +156,7 @@ impl StartCmd { let laddr = app_config().rpc_config.listen_addr; // TODO(liamsi): figure out how to handle the potential error on run std::thread::spawn(move || rpc::run(server, &laddr.to_string())); + status_info!("started RPC server:", laddr.to_string()); } } From d09ed05026e61c18db834a7bb7e4f0a0388858a9 Mon Sep 17 00:00:00 2001 From: Ismail Khoffi Date: Thu, 16 Jul 2020 15:22:18 +0200 Subject: [PATCH 05/15] Fix some typos while debugging --- light-client/src/light_client.rs | 2 +- light-client/src/peer_list.rs | 2 +- light-node/src/rpc.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/light-client/src/light_client.rs b/light-client/src/light_client.rs index 235a8517c..8a1e6f4f9 100644 --- a/light-client/src/light_client.rs +++ b/light-client/src/light_client.rs @@ -88,7 +88,7 @@ impl LightClient { /// Attempt to update the light client to the highest block of the primary node. /// - /// Note: This functin delegates the actual work to `verify_to_target`. + /// Note: This function delegates the actual work to `verify_to_target`. pub fn verify_to_highest(&mut self, state: &mut State) -> Result { let target_block = match self.io.fetch_light_block(self.peer, AtHeight::Highest) { Ok(last_block) => last_block, diff --git a/light-client/src/peer_list.rs b/light-client/src/peer_list.rs index 77b7776c3..10f026379 100644 --- a/light-client/src/peer_list.rs +++ b/light-client/src/peer_list.rs @@ -159,7 +159,7 @@ pub struct PeerListBuilder { } // This instance must be derived manually because the automatically -// derived instancce constrains T to be Default. +// derived instance constrains T to be Default. // See https://github.com/rust-lang/rust/issues/26925 impl Default for PeerListBuilder { fn default() -> Self { diff --git a/light-node/src/rpc.rs b/light-node/src/rpc.rs index 6427b2e5c..2ccfa78e5 100644 --- a/light-node/src/rpc.rs +++ b/light-node/src/rpc.rs @@ -9,7 +9,7 @@ pub use sealed::{Client, Rpc, Server}; /// Run the given [`Server`] on the given address and blocks until closed. /// -/// n.b. The underlying server has semantics to close on drop. Also does it not offer any way to +/// n.b. The underlying server has semantics to close on drop. Also does it does not offer any way to /// get the underlying Future to await, so we are left with this rather rudimentary way to control /// the lifecycle. Should we be interested in a more controlled way to close the server we can /// expose a handle in the future. From f064d54f8ffad15baf2edf31be5217cbd3229e02 Mon Sep 17 00:00:00 2001 From: Ismail Khoffi Date: Thu, 16 Jul 2020 15:39:03 +0200 Subject: [PATCH 06/15] Fix #450 :tada: thanks @OStevan :pray: --- light-client/src/store/memory.rs | 4 ++-- light-client/src/store/sled.rs | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/light-client/src/store/memory.rs b/light-client/src/store/memory.rs index e5a4fc7d6..c91c34cd6 100644 --- a/light-client/src/store/memory.rs +++ b/light-client/src/store/memory.rs @@ -65,8 +65,8 @@ impl LightStore for MemoryStore { fn latest(&self, status: Status) -> Option { self.store .iter() - .rev() - .find(|(_, e)| e.status == status) + .filter(|(_, e)| e.status == status) + .max_by_key(|(&height, _)| height) .map(|(_, e)| e.light_block.clone()) } diff --git a/light-client/src/store/sled.rs b/light-client/src/store/sled.rs index 456b9f2b0..5e5869b3c 100644 --- a/light-client/src/store/sled.rs +++ b/light-client/src/store/sled.rs @@ -72,7 +72,9 @@ impl LightStore for SledStore { } fn latest(&self, status: Status) -> Option { - self.db(status).iter(&self.db).next_back() + self.db(status) + .iter(&self.db) + .max_by(|first, second| first.height().cmp(&second.height())) } fn all(&self, status: Status) -> Box> { From 20fd8b66d47b8f65a897092e41e031c08e304acd Mon Sep 17 00:00:00 2001 From: Ismail Khoffi Date: Thu, 16 Jul 2020 15:58:46 +0200 Subject: [PATCH 07/15] add mock test for added rpc end-point --- light-node/src/rpc.rs | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/light-node/src/rpc.rs b/light-node/src/rpc.rs index 2ccfa78e5..52cda9b45 100644 --- a/light-node/src/rpc.rs +++ b/light-node/src/rpc.rs @@ -108,6 +108,7 @@ mod test { use tendermint_light_client::errors::Error; use tendermint_light_client::supervisor::Handle; + use tendermint_light_client::types::LatestStatus; use tendermint_light_client::types::LightBlock; use super::{Client, Rpc as _, Server}; @@ -127,6 +128,21 @@ mod test { assert_eq!(have, want); } + #[tokio::test] + async fn status() { + let server = Server::new(MockHandle {}); + let fut = { + let mut io = IoHandler::new(); + io.extend_with(server.to_delegate()); + let (client, server) = local::connect::(io); + client.status().join(server) + }; + let (have, _) = fut.compat().await.unwrap(); + let want = serde_json::from_str(STATUS_JSON).unwrap(); + + assert_eq!(have, want); + } + struct MockHandle; impl Handle for MockHandle { @@ -135,6 +151,11 @@ mod test { Ok(Some(block)) } + fn latest_status(&self) -> Result, Error> { + let status: LatestStatus = serde_json::from_str(STATUS_JSON).unwrap(); + + Ok(Some(status)) + } } const LIGHTBLOCK_JSON: &str = r#" @@ -255,4 +276,14 @@ mod test { "provider": "9D61B19DEFFD5A60BA844AF492EC2CC44449C569" } "#; + const STATUS_JSON: &str = r#" +{ + "block_hash": "5A55D7AF2DF9AE4BF4B46FDABBBAD1B66D37B5E044A4843AB0FB0EBEC3E0422C", + "connected_nodes": [ + "BADFADAD0BEFEEDC0C0ADEADBEEFC0FFEEFACADE", + "CEFEEDBADFADAD0C0CEEFACADE0ADEADBEEFC0FF" + ], + "height": 1565, + "valset_hash": "74F2AC2B6622504D08DD2509E28CE731985CFE4D133C9DB0CB85763EDCA95AA3" +}"#; } From 55e4b63b033c8b43bd8b43d0885c2d48faa55d41 Mon Sep 17 00:00:00 2001 From: Ismail Khoffi Date: Thu, 16 Jul 2020 16:10:43 +0200 Subject: [PATCH 08/15] Refer to additional RPC endpoint in README.md --- light-node/README.md | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/light-node/README.md b/light-node/README.md index 1097df48c..151f113f5 100644 --- a/light-node/README.md +++ b/light-node/README.md @@ -106,8 +106,41 @@ $ curl localhost:8888 -X POST -H 'Content-Type: application/json' \ -d '{"jsonrpc": "2.0", "method": "state", "id": 1}' | jq ``` +Or you can query a shorter summary via the `/status` endpoint: +``` +$ curl localhost:8888 -X POST -H 'Content-Type: application/json'\ 15:58:52 + -d '{"jsonrpc": "2.0", "method": "status", "id": 1}' | jq + +``` + +
+ Click here to see an example for expected output for the status endpoint: + +``` +$curl localhost:8888 -X POST -H 'Content-Type: application/json'\ 15:58:52 + -d '{"jsonrpc": "2.0", "method": "status", "id": 1}' | jq + % Total % Received % Xferd Average Speed Time Time Time Current + Dload Upload Total Spent Left Speed +100 364 100 317 100 47 1843 273 --:--:-- --:--:-- --:--:-- 2104 +``` +```json +{ + "jsonrpc": "2.0", + "result": { + "block_hash": "ED745723430944215F65ED78AD7DF9ED0AA8A2A3B465BF421E0BAF66AA55AA08", + "connected_nodes": [ + "BADFADAD0BEFEEDC0C0ADEADBEEFC0FFEEFACADE", + "CEFEEDBADFADAD0C0CEEFACADE0ADEADBEEFC0FF" + ], + "height": 3850, + "valset_hash": "74F2AC2B6622504D08DD2509E28CE731985CFE4D133C9DB0CB85763EDCA95AA3" + }, + "id": 1 +} +``` +
- Click here to see an example for expected output: + Click here to see an example for expected output for the state endpoint: Command: ``` From 07aedb0fcf0e74b9ade5306f1a746a617ab6ecc1 Mon Sep 17 00:00:00 2001 From: Ismail Khoffi Date: Thu, 16 Jul 2020 16:21:57 +0200 Subject: [PATCH 09/15] Update Changelog --- CHANGES.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index f7a77f6b3..991b26f7b 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -17,10 +17,14 @@ - Correctly handle blocks marked `Trusted` in accordance with the specification ([#407]) - Treat `Trusted` status as a special case of `Verified` as per the spec ([#419]) - Add integration test ([#431]) +- Reworked light-node to `Supervisor` / `Handle` ([#430]) +- Add `latest_status` to the supervisor `Handle` ([#449]) +- Add JSONRPC endpoints to query the light-node ([#363], [#449]) [#302]: https://github.com/informalsystems/tendermint-rs/pull/302 [#336]: https://github.com/informalsystems/tendermint-rs/pull/336 [#360]: https://github.com/informalsystems/tendermint-rs/pull/360 +[#363]: https://github.com/informalsystems/tendermint-rs/pull/363 [#364]: https://github.com/informalsystems/tendermint-rs/pull/364 [#365]: https://github.com/informalsystems/tendermint-rs/pull/365 [#371]: https://github.com/informalsystems/tendermint-rs/pull/371 @@ -32,7 +36,9 @@ [#403]: https://github.com/informalsystems/tendermint-rs/pull/403 [#407]: https://github.com/informalsystems/tendermint-rs/pull/407 [#419]: https://github.com/informalsystems/tendermint-rs/pull/419 +[#430]: https://github.com/informalsystems/tendermint-rs/pull/430 [#431]: https://github.com/informalsystems/tendermint-rs/pull/431 +[#449]: https://github.com/informalsystems/tendermint-rs/pull/449 [ADR-007]: https://github.com/informalsystems/tendermint-rs/blob/master/docs/architecture/adr-007-light-client-supervisor-ergonomics.md From d16dcd7011052ea834b05612a2000d588bb6bc31 Mon Sep 17 00:00:00 2001 From: Ismail Khoffi Date: Thu, 16 Jul 2020 16:25:17 +0200 Subject: [PATCH 10/15] Fix example in README.md --- light-node/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/light-node/README.md b/light-node/README.md index 151f113f5..301c89af8 100644 --- a/light-node/README.md +++ b/light-node/README.md @@ -117,8 +117,8 @@ $ curl localhost:8888 -X POST -H 'Content-Type: application/json'\ Click here to see an example for expected output for the status endpoint: ``` -$curl localhost:8888 -X POST -H 'Content-Type: application/json'\ 15:58:52 - -d '{"jsonrpc": "2.0", "method": "status", "id": 1}' | jq +$ curl localhost:8888 -X POST -H 'Content-Type: application/json' \ + -d '{"jsonrpc": "2.0", "method": "status", "id": 1}' | jq % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 364 100 317 100 47 1843 273 --:--:-- --:--:-- --:--:-- 2104 From 58af5781e65b1e5ddeac360e37e005b86eb5dc43 Mon Sep 17 00:00:00 2001 From: Ismail Khoffi Date: Thu, 16 Jul 2020 16:28:50 +0200 Subject: [PATCH 11/15] Update CHANGES.md --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 991b26f7b..9aca025d8 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -17,7 +17,7 @@ - Correctly handle blocks marked `Trusted` in accordance with the specification ([#407]) - Treat `Trusted` status as a special case of `Verified` as per the spec ([#419]) - Add integration test ([#431]) -- Reworked light-node to `Supervisor` / `Handle` ([#430]) +- Rework light-node CLI to use `Supervisor` / `Handle` ([#430]) - Add `latest_status` to the supervisor `Handle` ([#449]) - Add JSONRPC endpoints to query the light-node ([#363], [#449]) From 316eb5846df75d0b668a1f8ad32e9aea7faf6c21 Mon Sep 17 00:00:00 2001 From: Ismail Khoffi Date: Thu, 16 Jul 2020 17:39:15 +0200 Subject: [PATCH 12/15] Fix README.md: Add closing `
` for 1st example --- light-node/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/light-node/README.md b/light-node/README.md index 301c89af8..07f7a5ab8 100644 --- a/light-node/README.md +++ b/light-node/README.md @@ -138,6 +138,7 @@ $ curl localhost:8888 -X POST -H 'Content-Type: application/json' \ "id": 1 } ``` +
Click here to see an example for expected output for the state endpoint: From 31d32a29e7f9bdc3216de24befed91930da679fb Mon Sep 17 00:00:00 2001 From: Ismail Khoffi Date: Thu, 16 Jul 2020 18:16:30 +0200 Subject: [PATCH 13/15] Make all fields but connected_nodes optional --- light-client/src/supervisor.rs | 24 ++++++++++++------------ light-client/src/types.rs | 12 ++++++------ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/light-client/src/supervisor.rs b/light-client/src/supervisor.rs index a19c06079..3c6cb73d2 100644 --- a/light-client/src/supervisor.rs +++ b/light-client/src/supervisor.rs @@ -176,19 +176,19 @@ impl Supervisor { /// Return latest trusted status summary. fn latest_status(&mut self) -> Option { let latest_trusted = self.peers.primary().latest_trusted(); + let mut connected_nodes: Vec = Vec::new(); + connected_nodes.push(self.peers.primary_id()); + connected_nodes.append(&mut self.peers.witnesses_ids().iter().copied().collect()); + match latest_trusted { - Some(trusted) => { - let mut connected_nodes: Vec = Vec::new(); - connected_nodes.push(self.peers.primary_id()); - connected_nodes.append(&mut self.peers.witnesses_ids().iter().copied().collect()); - Some(LatestStatus::new( - trusted.signed_header.header.height(), - trusted.signed_header.header.hash(), - trusted.next_validators.hash(), - connected_nodes, - )) - } - None => None, + Some(trusted) => Some(LatestStatus::new( + Some(trusted.signed_header.header.height()), + Some(trusted.signed_header.header.hash()), + Some(trusted.next_validators.hash()), + connected_nodes, + )), + // only return connected nodes to see what is going on: + None => Some(LatestStatus::new(None, None, None, connected_nodes)), } } diff --git a/light-client/src/types.rs b/light-client/src/types.rs index 3d06df8bd..e6c1c56af 100644 --- a/light-client/src/types.rs +++ b/light-client/src/types.rs @@ -122,21 +122,21 @@ impl LightBlock { #[display(fmt = "{:?}", self)] pub struct LatestStatus { /// The latest height we are trusting. - pub height: Height, + pub height: Option, /// The latest block hash we are trusting. - pub block_hash: Hash, + pub block_hash: Option, /// The latest validator set we are trusting. /// Note that this potentially did not yet sign a header yet. - pub valset_hash: Hash, + pub valset_hash: Option, /// The list of fullnodes we are connected to, primary and witnesses. pub connected_nodes: Vec, } impl LatestStatus { pub fn new( - height: u64, - block_hash: Hash, - valset_hash: Hash, + height: Option, + block_hash: Option, + valset_hash: Option, connected_nodes: Vec, ) -> Self { LatestStatus { From bc8a63581799b546a393ad633cec7f33112a7b4c Mon Sep 17 00:00:00 2001 From: Ismail Khoffi Date: Thu, 16 Jul 2020 18:22:15 +0200 Subject: [PATCH 14/15] Always return a status instead --- light-client/src/supervisor.rs | 18 +++++++++--------- light-node/src/rpc.rs | 8 ++++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/light-client/src/supervisor.rs b/light-client/src/supervisor.rs index 3c6cb73d2..f076d7ea5 100644 --- a/light-client/src/supervisor.rs +++ b/light-client/src/supervisor.rs @@ -18,7 +18,7 @@ pub trait Handle { todo!() } - fn latest_status(&self) -> Result, Error> { + fn latest_status(&self) -> Result { todo!() } @@ -51,7 +51,7 @@ enum HandleInput { /// Get the latest trusted block. LatestTrusted(channel::Sender>), /// Get the current status of the LightClient - GetStatus(channel::Sender>), + GetStatus(channel::Sender), } /// A light client `Instance` packages a `LightClient` together with its `State`. @@ -64,7 +64,7 @@ pub struct Instance { } impl Instance { - /// Constructs a new instance from the given light client and its state. + /// Constructs a new instance from the givlight-client/src/supervisor.rs:399:42en light client and its state. pub fn new(light_client: LightClient, state: State) -> Self { Self { light_client, @@ -174,21 +174,21 @@ impl Supervisor { } /// Return latest trusted status summary. - fn latest_status(&mut self) -> Option { + fn latest_status(&mut self) -> LatestStatus { let latest_trusted = self.peers.primary().latest_trusted(); let mut connected_nodes: Vec = Vec::new(); connected_nodes.push(self.peers.primary_id()); connected_nodes.append(&mut self.peers.witnesses_ids().iter().copied().collect()); match latest_trusted { - Some(trusted) => Some(LatestStatus::new( + Some(trusted) => LatestStatus::new( Some(trusted.signed_header.header.height()), Some(trusted.signed_header.header.hash()), Some(trusted.next_validators.hash()), connected_nodes, - )), + ), // only return connected nodes to see what is going on: - None => Some(LatestStatus::new(None, None, None, connected_nodes)), + None => LatestStatus::new(None, None, None, connected_nodes), } } @@ -393,8 +393,8 @@ impl Handle for SupervisorHandle { Ok(receiver.recv().map_err(ErrorKind::from)?) } - fn latest_status(&self) -> Result, Error> { - let (sender, receiver) = channel::bounded::>(1); + fn latest_status(&self) -> Result { + let (sender, receiver) = channel::bounded::(1); self.sender .send(HandleInput::GetStatus(sender)) .map_err(ErrorKind::from)?; diff --git a/light-node/src/rpc.rs b/light-node/src/rpc.rs index 52cda9b45..5315c2429 100644 --- a/light-node/src/rpc.rs +++ b/light-node/src/rpc.rs @@ -49,7 +49,7 @@ mod sealed { /// Returns the latest status. #[rpc(name = "status")] - fn status(&self) -> FutureResult, Error>; + fn status(&self) -> FutureResult; } pub use self::rpc_impl_Rpc::gen_client::Client; @@ -85,7 +85,7 @@ mod sealed { future::result(res) } - fn status(&self) -> FutureResult, Error> { + fn status(&self) -> FutureResult { let res = self.handle.latest_status().map_err(|e| { let mut err = Error::internal_error(); err.message = e.to_string(); @@ -151,10 +151,10 @@ mod test { Ok(Some(block)) } - fn latest_status(&self) -> Result, Error> { + fn latest_status(&self) -> Result { let status: LatestStatus = serde_json::from_str(STATUS_JSON).unwrap(); - Ok(Some(status)) + Ok(status) } } From d830c28957da4001e4e4bfb49f291c97c8cc4311 Mon Sep 17 00:00:00 2001 From: Ismail Khoffi Date: Thu, 16 Jul 2020 18:30:05 +0200 Subject: [PATCH 15/15] Fix paste err (thx @xla) --- light-client/src/supervisor.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/light-client/src/supervisor.rs b/light-client/src/supervisor.rs index f076d7ea5..6100b8528 100644 --- a/light-client/src/supervisor.rs +++ b/light-client/src/supervisor.rs @@ -64,7 +64,7 @@ pub struct Instance { } impl Instance { - /// Constructs a new instance from the givlight-client/src/supervisor.rs:399:42en light client and its state. + /// Constructs a new instance from the given light client and its state. pub fn new(light_client: LightClient, state: State) -> Self { Self { light_client,