summaryrefslogtreecommitdiff
path: root/unique_ids/src/main.rs
blob: 3787033cc1fa2f5015b14f871364dd4c634e8351 (plain)
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
    }
}