1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
use std::{
io,
time::{SystemTime, UNIX_EPOCH},
};
use common::{run_with, Handler};
use rand::{rngs::StdRng, Rng, SeedableRng};
use serde::{Deserialize, Serialize};
fn main() {
run_with::<UniqueIdsHandler>(io::stdin(), io::stdout())
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(tag = "type")]
enum UniqueIdsBody {
#[serde(rename = "generate")]
Generate { msg_id: usize },
#[serde(rename = "generate_ok")]
GenerateOk {
msg_id: usize,
in_reply_to: usize,
id: u128,
},
}
type RngMethod = StdRng;
struct UniqueIdsHandler {
rng: RngMethod,
next_msg_id: usize,
}
impl Handler for UniqueIdsHandler {
type Body = UniqueIdsBody;
fn init(_node_id: String, _node_ids: Vec<String>, _msg_id: usize) -> Self {
Self {
rng: RngMethod::from_entropy(), // TODO: This could be seeded from the node ID
next_msg_id: 1,
}
}
fn handle(
&mut self,
header: common::msg::MessageHeader,
body: Self::Body,
writer: &mut common::MsgWriter<impl std::io::Write>,
) -> () {
match body {
UniqueIdsBody::Generate { msg_id } => {
let id = self.gen_id();
writer.write(
header.src,
&UniqueIdsBody::GenerateOk {
msg_id: self.next_msg_id,
in_reply_to: msg_id,
id,
},
);
self.next_msg_id += 1;
}
UniqueIdsBody::GenerateOk { .. } => (),
};
}
}
impl UniqueIdsHandler {
fn gen_id(&mut self) -> u128 {
// Time since UNIX epoch in milliseconds
let now = SystemTime::now();
let time_millis: u128 = now.duration_since(UNIX_EPOCH).unwrap().as_millis();
// 80 bits of randomness
let rand1: u16 = self.rng.gen();
let rand2: u64 = self.rng.gen();
let rand: u128 = rand1 as u128 | ((rand2 as u128) << 64);
(time_millis << 80) | rand
}
}
|