tower_defense/auth/
timestamp.rs1use std::{
2 collections::HashMap,
3 sync::{Arc, Mutex},
4 time::{Duration, UNIX_EPOCH},
5};
6
7use crate::{crypto::PeerId, error::Error};
8
9pub trait VerifyTimestamp {
10 fn verify(&self, peer: &PeerId, timestamp: u64) -> bool;
11}
12
13#[derive(Debug, Clone)]
14pub struct WithinDuration(pub Duration);
15
16impl VerifyTimestamp for WithinDuration {
17 fn verify(&self, _peer: &PeerId, timestamp: u64) -> bool {
18 let Ok(now) = now() else {
19 return false;
21 };
22
23 Duration::from_millis(now.abs_diff(timestamp)) < self.0
24 }
25}
26
27#[derive(Debug, Clone)]
28pub struct LaterThanLast {
29 log: Arc<Mutex<HashMap<PeerId, u64>>>,
30}
31
32impl Default for LaterThanLast {
33 fn default() -> Self {
34 Self {
35 log: Arc::new(Mutex::new(HashMap::new())),
36 }
37 }
38}
39
40impl VerifyTimestamp for LaterThanLast {
41 fn verify(&self, peer: &PeerId, timestamp: u64) -> bool {
42 let Ok(mut log) = self.log.lock() else {
43 return false;
44 };
45
46 let Some(last) = log.get(peer) else {
47 log.insert(peer.clone(), timestamp);
48 return true;
49 };
50
51 if *last >= timestamp {
52 return false;
53 }
54
55 log.insert(peer.clone(), timestamp);
56
57 true
58 }
59}
60
61pub(crate) fn now() -> Result<u64, Error> {
63 let millis = std::time::SystemTime::now()
64 .duration_since(UNIX_EPOCH)?
65 .as_millis();
66
67 Ok(u64::try_from(millis)?)
68}