From 981f4de39764de296577991acba3ffdcf51042c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Thu, 7 May 2020 17:08:39 +0100 Subject: [PATCH] Requiring explicit timestamp when converting from rest to service mixnodes (#224) --- .../src/network/rest/presence/conversions.rs | 45 ++++++++++++------- .../src/network/rest/presence/mixnode.rs | 10 ++++- validator/src/network/rest/presence/models.rs | 27 +++++++++++ 3 files changed, 64 insertions(+), 18 deletions(-) diff --git a/validator/src/network/rest/presence/conversions.rs b/validator/src/network/rest/presence/conversions.rs index 703d97000b..5e3c22647c 100644 --- a/validator/src/network/rest/presence/conversions.rs +++ b/validator/src/network/rest/presence/conversions.rs @@ -1,21 +1,22 @@ +use super::models::Timestamp; use crate::network::rest::presence::models::Mixnode as RestMixnode; use crate::network::rest::presence::models::Topology as RestTopology; use crate::services::mixmining::models::Mixnode as ServiceMixnode; use crate::services::mixmining::models::Topology as ServiceTopology; use std::convert::From; -use std::time::{SystemTime, UNIX_EPOCH}; -impl From for ServiceMixnode { - fn from(value: RestMixnode) -> ServiceMixnode { - let now = SystemTime::now(); - let timestamp = now.duration_since(UNIX_EPOCH).unwrap().as_millis() as u64; +impl ServiceMixnode { + pub fn from_rest_mixnode_with_timestamp( + rest_mix: RestMixnode, + timestamp: Timestamp, + ) -> ServiceMixnode { ServiceMixnode { - host: value.host, - last_seen: timestamp, - location: value.location, - public_key: value.public_key, + host: rest_mix.host, + last_seen: timestamp.into(), + location: rest_mix.location, + public_key: rest_mix.public_key, stake: 0, - version: value.version, + version: rest_mix.version, } } } @@ -31,11 +32,16 @@ impl From for RestMixnode { } } -impl From for ServiceTopology { - fn from(value: RestTopology) -> ServiceTopology { +impl ServiceTopology { + pub fn from_rest_topology_with_timestamp( + rest_topology: RestTopology, + timestamp: Timestamp, + ) -> ServiceTopology { let mut converted_mixnodes: Vec = Vec::new(); - for mixnode in value.mixnodes { - converted_mixnodes.push(mixnode.into()); + for mixnode in rest_topology.mixnodes { + converted_mixnodes.push(ServiceMixnode::from_rest_mixnode_with_timestamp( + mixnode, timestamp, + )); } ServiceTopology { mixnodes: converted_mixnodes.to_vec(), @@ -86,7 +92,9 @@ mod test_presence_conversions_for_mixmining_service { #[test] fn test_building_service_mixnode_from_rest_mixnode() { let rest_mixnode = rest_mixnode_fixture(); - let service_mixnode = ServiceMixnode::from(rest_mixnode.clone()); + let timestamp = Timestamp::default(); + let service_mixnode = + ServiceMixnode::from_rest_mixnode_with_timestamp(rest_mixnode.clone(), timestamp); assert_eq!(service_mixnode.host, rest_mixnode.host); assert_eq!(service_mixnode.public_key, rest_mixnode.public_key); assert_eq!(service_mixnode.location, rest_mixnode.location); @@ -116,8 +124,11 @@ mod test_presence_conversions_for_mixmining_service { validators: vec![], }; - let service_topology = ServiceTopology::from(rest_topology); - let service_mixnode = ServiceMixnode::from(rest_mixnode); + let timestamp = Timestamp::default(); + let service_topology = + ServiceTopology::from_rest_topology_with_timestamp(rest_topology, timestamp); + let service_mixnode = + ServiceMixnode::from_rest_mixnode_with_timestamp(rest_mixnode, timestamp); assert_eq!(service_mixnode, service_topology.mixnodes[0]); } } diff --git a/validator/src/network/rest/presence/mixnode.rs b/validator/src/network/rest/presence/mixnode.rs index ed4f46d229..3d1dee8666 100644 --- a/validator/src/network/rest/presence/mixnode.rs +++ b/validator/src/network/rest/presence/mixnode.rs @@ -1,8 +1,10 @@ use super::*; use crate::network::rest::presence::models::Mixnode as PresenceMixnode; +use crate::services::mixmining::models::Mixnode as ServiceMixnode; use bodyparser::Struct; use iron::status; use iron::Handler; +use models::Timestamp; pub struct CreatePresence { service: Arc>, @@ -22,7 +24,13 @@ impl Handler for CreatePresence { let mixnode = json_parse .unwrap() .expect("Unexpected JSON parsing problem"); - self.service.lock().unwrap().add(mixnode.into()); + self.service + .lock() + .unwrap() + .add(ServiceMixnode::from_rest_mixnode_with_timestamp( + mixnode, + Timestamp::default(), + )); Ok(Response::with(status::Created)) } else { let error = json_parse.unwrap_err(); diff --git a/validator/src/network/rest/presence/models.rs b/validator/src/network/rest/presence/models.rs index 60293d930d..b4efde2808 100644 --- a/validator/src/network/rest/presence/models.rs +++ b/validator/src/network/rest/presence/models.rs @@ -1,4 +1,5 @@ use serde::{Deserialize, Serialize}; +use std::time::{SystemTime, UNIX_EPOCH}; #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] @@ -37,3 +38,29 @@ pub struct Validator { last_seen: u64, location: String, } + +#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy, PartialOrd, Ord)] +pub struct Timestamp(u64); + +impl Default for Timestamp { + fn default() -> Timestamp { + Timestamp( + SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap() + .as_millis() as u64, + ) + } +} + +impl From for Timestamp { + fn from(v: u64) -> Timestamp { + Timestamp(v) + } +} + +impl Into for Timestamp { + fn into(self) -> u64 { + self.0 + } +}