-
Notifications
You must be signed in to change notification settings - Fork 237
/
Copy pathmixnode.rs
127 lines (115 loc) · 3.82 KB
/
mixnode.rs
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
// Copyright 2020 Nym Technologies SA
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use crate::models::node::NodeInfo;
use crypto::asymmetric::{encryption, identity};
use serde::{Deserialize, Serialize};
use std::convert::TryInto;
use std::io;
use std::net::ToSocketAddrs;
#[derive(Debug)]
pub enum ConversionError {
InvalidIdentityKeyError(identity::KeyRecoveryError),
InvalidSphinxKeyError(encryption::KeyRecoveryError),
InvalidAddress(io::Error),
}
impl From<encryption::KeyRecoveryError> for ConversionError {
fn from(err: encryption::KeyRecoveryError) -> Self {
ConversionError::InvalidSphinxKeyError(err)
}
}
impl From<identity::KeyRecoveryError> for ConversionError {
fn from(err: identity::KeyRecoveryError) -> Self {
ConversionError::InvalidIdentityKeyError(err)
}
}
// used for mixnode to register themselves
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct MixRegistrationInfo {
#[serde(flatten)]
pub(crate) node_info: NodeInfo,
pub(crate) layer: u64,
}
impl MixRegistrationInfo {
pub fn new(
mix_host: String,
identity_key: String,
sphinx_key: String,
version: String,
location: String,
layer: u64,
incentives_address: Option<String>,
) -> Self {
MixRegistrationInfo {
node_info: NodeInfo {
mix_host,
identity_key,
sphinx_key,
version,
location,
incentives_address: incentives_address.unwrap_or_else(|| "".to_string()),
},
layer,
}
}
}
// actual entry in topology
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct RegisteredMix {
#[serde(flatten)]
pub(crate) mix_info: MixRegistrationInfo,
pub(crate) registration_time: i64,
pub(crate) reputation: i64,
}
impl RegisteredMix {
pub fn identity(&self) -> String {
self.mix_info.node_info.identity_key.clone()
}
pub fn mix_host(&self) -> String {
self.mix_info.node_info.mix_host.clone()
}
}
impl TryInto<topology::mix::Node> for RegisteredMix {
type Error = ConversionError;
fn try_into(self) -> Result<topology::mix::Node, Self::Error> {
let resolved_hostname = self
.mix_info
.node_info
.mix_host
.to_socket_addrs()
.map_err(|err| ConversionError::InvalidAddress(err))?
.next()
.ok_or_else(|| {
ConversionError::InvalidAddress(io::Error::new(
io::ErrorKind::Other,
"no valid socket address",
))
})?;
Ok(topology::mix::Node {
location: self.mix_info.node_info.location,
host: resolved_hostname,
identity_key: identity::PublicKey::from_base58_string(
self.mix_info.node_info.identity_key,
)?,
sphinx_key: encryption::PublicKey::from_base58_string(
self.mix_info.node_info.sphinx_key,
)?,
layer: self.mix_info.layer,
registration_time: self.registration_time,
reputation: self.reputation,
version: self.mix_info.node_info.version,
})
}
}