diff --git a/Cargo.lock b/Cargo.lock index 07341e2d34..8e70bb3cfb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1639,7 +1639,9 @@ dependencies = [ "iron", "log 0.4.8", "pretty_env_logger", + "router", "serde", + "serde_json", "tempfile", "tokio 0.2.12", "topology", @@ -2249,6 +2251,23 @@ dependencies = [ "winreg", ] +[[package]] +name = "route-recognizer" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea509065eb0b3c446acdd0102f0d46567dc30902dc0be91d6552035d92b0f4f8" + +[[package]] +name = "router" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc63b6f3b8895b0d04e816b2b1aa58fdba2d5acca3cbb8f0ab8e017347d57397" +dependencies = [ + "iron", + "route-recognizer", + "url 1.7.2", +] + [[package]] name = "rust-argon2" version = "0.7.0" diff --git a/validator/Cargo.toml b/validator/Cargo.toml index 0abfa6c7d6..f000bdb199 100644 --- a/validator/Cargo.toml +++ b/validator/Cargo.toml @@ -18,7 +18,9 @@ futures = "0.3.1" iron = "0.6.1" log = "0.4" pretty_env_logger = "0.3" +router = "0.6.0" serde = "1.0.104" +serde_json = "1.0.48" tokio = { version = "0.2", features = ["full"] } ## internal diff --git a/validator/src/network/rest/mod.rs b/validator/src/network/rest/mod.rs index 30d94edc48..17a87785b9 100644 --- a/validator/src/network/rest/mod.rs +++ b/validator/src/network/rest/mod.rs @@ -1,5 +1,8 @@ use iron::prelude::*; -use iron::status; +use router::Router; + +mod models; +mod routes; pub struct Api {} @@ -11,8 +14,16 @@ impl Api { pub async fn run(self) { let port = 3000; println!("* starting REST API on localhost:{}", port); - Iron::new(|_: &mut Request| Ok(Response::with((status::Ok, "Hello World!")))) + + let router = self.setup_routes(); + Iron::new(router) .http(format!("localhost:{}", port)) .unwrap(); } + + pub fn setup_routes(&self) -> Router { + let mut router = Router::new(); + router.get("/topology", routes::topology::get, "topology_get"); + router + } } diff --git a/validator/src/network/rest/models/mod.rs b/validator/src/network/rest/models/mod.rs new file mode 100644 index 0000000000..bb4ee05c5c --- /dev/null +++ b/validator/src/network/rest/models/mod.rs @@ -0,0 +1 @@ +pub mod presence; diff --git a/validator/src/network/rest/models/presence.rs b/validator/src/network/rest/models/presence.rs new file mode 100644 index 0000000000..300e80ca6d --- /dev/null +++ b/validator/src/network/rest/models/presence.rs @@ -0,0 +1,36 @@ +use serde::{Deserialize, Serialize}; + +// Topology shows us the current state of the overall Nym network +#[derive(Serialize, Deserialize, Debug)] +pub struct Topology { + pub validators: Vec, + pub mix_nodes: Vec, + pub service_providers: Vec, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct Validator { + host: String, + public_key: String, + version: String, + last_seen: u64, + location: String, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct MixNode { + host: String, + public_key: String, + version: String, + last_seen: u64, + location: String, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct ServiceProvider { + host: String, + public_key: String, + version: String, + last_seen: u64, + location: String, +} diff --git a/validator/src/network/rest/routes/mod.rs b/validator/src/network/rest/routes/mod.rs new file mode 100644 index 0000000000..1265efcf40 --- /dev/null +++ b/validator/src/network/rest/routes/mod.rs @@ -0,0 +1,4 @@ +use iron::prelude::*; +use iron::status; + +pub mod topology; diff --git a/validator/src/network/rest/routes/topology.rs b/validator/src/network/rest/routes/topology.rs new file mode 100644 index 0000000000..2b72ccad3f --- /dev/null +++ b/validator/src/network/rest/routes/topology.rs @@ -0,0 +1,12 @@ +use super::*; +use crate::network::rest::models::presence::{MixNode, ServiceProvider, Topology, Validator}; + +pub fn get(_req: &mut Request) -> IronResult { + let topology = Topology { + mix_nodes: Vec::::new(), + service_providers: Vec::::new(), + validators: Vec::::new(), + }; + let response = serde_json::to_string_pretty(&topology).unwrap(); + Ok(Response::with((status::Ok, response))) +} diff --git a/validator/src/validator.rs b/validator/src/validator.rs index da14ac78ac..9c12cef95a 100644 --- a/validator/src/validator.rs +++ b/validator/src/validator.rs @@ -6,7 +6,6 @@ use crypto::identity::MixIdentityKeyPair; use healthcheck::HealthChecker; use tokio::runtime::Runtime; -// allow for a generic validator pub struct Validator { // when you re-introduce keys, check which ones you want: // MixIdentityKeyPair (like 'nym-client' ) <- probably that one (after maybe renaming to just identity::KeyPair) @@ -16,7 +15,6 @@ pub struct Validator { rest_api: rest::Api, } -// but for time being, since it's a dummy one, have it use dummy keys impl Validator { pub fn new(config: Config) -> Self { let dummy_healthcheck_keypair = MixIdentityKeyPair::new(); @@ -44,14 +42,17 @@ impl Validator { } } + // TODO: Fix Tendermint startup here, see https://github.com/nymtech/nym/issues/147 pub fn start(self) { let mut rt = Runtime::new().unwrap(); rt.spawn(self.health_check_runner.run()); rt.spawn(self.rest_api.run()); rt.spawn(self.tendermint_abci.run()); - println!("Validator startup complete."); // TODO: Not immensely important to me right now, but why doesn't this get hit? + + // TODO: this message is going to come out of order (if at all), as spawns are async + println!("Validator startup complete."); rt.block_on(blocker()); } } -pub async fn blocker() {} +pub async fn blocker() {} // once Tendermint unblocks us, make this block forever.