Feature/GitHub actions and clippy cleanup (#493)
* Added github actions templates * removed travis .yml file * initial clippy cleanup pass * fixed the rest of clippy warnings * Made github badges more fancy and consistent with the ones in sphinx * Updated local rustc version and removed compilation warningns * ... and fresh clippy warnings * formatting * beta clippy specific warnings fixed * Fixed all nightly clippy warnings * Fixed trying to unwrap a () * Actually running all tests * Correctly passing the --all flag * Hopefullly third time's a charm in fixing argument passing
This commit is contained in:
committed by
GitHub
parent
131574cd3c
commit
2d3b4f4b91
@@ -0,0 +1,44 @@
|
||||
name: Continuous integration
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
ci:
|
||||
runs-on: ubuntu-latest
|
||||
continue-on-error: ${{ matrix.rust == 'nightly' }}
|
||||
strategy:
|
||||
matrix:
|
||||
rust:
|
||||
- stable
|
||||
- beta
|
||||
- nightly
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
profile: minimal
|
||||
toolchain: ${{ matrix.rust }}
|
||||
override: true
|
||||
components: rustfmt, clippy
|
||||
|
||||
- uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: build
|
||||
args: --all
|
||||
|
||||
- uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: test
|
||||
args: --all
|
||||
|
||||
- uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: fmt
|
||||
args: --all -- --check
|
||||
|
||||
- uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: clippy
|
||||
args: -- -D warnings
|
||||
@@ -0,0 +1,14 @@
|
||||
name: Clippy check
|
||||
|
||||
on: push
|
||||
|
||||
jobs:
|
||||
clippy_check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- run: rustup component add clippy
|
||||
- uses: actions-rs/clippy-check@v1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
args: --all-features
|
||||
-15
@@ -1,15 +0,0 @@
|
||||
language: rust
|
||||
rust:
|
||||
- stable
|
||||
- beta
|
||||
- nightly
|
||||
jobs:
|
||||
allow_failures:
|
||||
- rust: nightly
|
||||
fast_finish: true
|
||||
before_script:
|
||||
- rustup component add rustfmt
|
||||
script:
|
||||
- cargo build
|
||||
- cargo test --all
|
||||
- cargo fmt -- --check
|
||||
Generated
+3
@@ -889,6 +889,7 @@ dependencies = [
|
||||
"gateway-requests",
|
||||
"log",
|
||||
"nymsphinx",
|
||||
"rand",
|
||||
"tokio",
|
||||
"tokio-tungstenite",
|
||||
"tungstenite",
|
||||
@@ -1612,6 +1613,7 @@ dependencies = [
|
||||
"nymsphinx",
|
||||
"pemstore",
|
||||
"pretty_env_logger",
|
||||
"rand",
|
||||
"serde",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
@@ -1729,6 +1731,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"crypto",
|
||||
"nymsphinx-types",
|
||||
"rand",
|
||||
"serde",
|
||||
]
|
||||
|
||||
|
||||
@@ -11,7 +11,9 @@ The platform is composed of multiple Rust crates. Top-level executable binary cr
|
||||
* nym-network-monitor - sends packets through the full system to check that they are working as expected, and stores node uptime histories as the basis of a rewards system ("mixmining" or "proof-of-mixing").
|
||||
* nym-explorer - a (projected) block explorer and (existing) mixnet viewer.
|
||||
|
||||
[](https://travis-ci.com/nymtech/nym)
|
||||
[](https://opensource.org/licenses/Apache-2.0)
|
||||
[](https://github.com/nymtech/nym/actions?query=branch%3Adevelop)
|
||||
|
||||
|
||||
### Building
|
||||
|
||||
|
||||
@@ -61,8 +61,8 @@ impl KeyManager {
|
||||
R: RngCore + CryptoRng,
|
||||
{
|
||||
KeyManager {
|
||||
identity_keypair: Arc::new(identity::KeyPair::new_with_rng(rng)),
|
||||
encryption_keypair: Arc::new(encryption::KeyPair::new_with_rng(rng)),
|
||||
identity_keypair: Arc::new(identity::KeyPair::new(rng)),
|
||||
encryption_keypair: Arc::new(encryption::KeyPair::new(rng)),
|
||||
gateway_shared_key: None,
|
||||
ack_key: Arc::new(AckKey::new(rng)),
|
||||
}
|
||||
|
||||
+3
@@ -49,6 +49,9 @@ impl<R> InputMessageListener<R>
|
||||
where
|
||||
R: CryptoRng + Rng,
|
||||
{
|
||||
// at this point I'm not entirely sure how to deal with this warning without
|
||||
// some considerable refactoring
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub(super) fn new(
|
||||
ack_key: Arc<AckKey>,
|
||||
ack_recipient: Recipient,
|
||||
|
||||
@@ -73,6 +73,9 @@ pub struct Config {
|
||||
}
|
||||
|
||||
impl Config {
|
||||
// at this point I'm not entirely sure how to deal with this warning without
|
||||
// some considerable refactoring
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
ack_key: Arc<AckKey>,
|
||||
ack_wait_multiplier: f64,
|
||||
|
||||
@@ -117,7 +117,7 @@ type BatchRealMessageReceiver = mpsc::UnboundedReceiver<Vec<RealMessage>>;
|
||||
|
||||
pub(crate) enum StreamMessage {
|
||||
Cover,
|
||||
Real(RealMessage),
|
||||
Real(Box<RealMessage>),
|
||||
}
|
||||
|
||||
impl<R> Stream for OutQueueControl<R>
|
||||
@@ -145,7 +145,7 @@ where
|
||||
|
||||
// check if we have anything immediately available
|
||||
if let Some(real_available) = self.received_buffer.pop_front() {
|
||||
return Poll::Ready(Some(StreamMessage::Real(real_available)));
|
||||
return Poll::Ready(Some(StreamMessage::Real(Box::new(real_available))));
|
||||
}
|
||||
|
||||
// decide what kind of message to send
|
||||
@@ -158,9 +158,9 @@ where
|
||||
Poll::Ready(Some(real_messages)) => {
|
||||
self.received_buffer = real_messages.into();
|
||||
// we MUST HAVE received at least ONE message
|
||||
Poll::Ready(Some(StreamMessage::Real(
|
||||
Poll::Ready(Some(StreamMessage::Real(Box::new(
|
||||
self.received_buffer.pop_front().unwrap(),
|
||||
)))
|
||||
))))
|
||||
}
|
||||
|
||||
// otherwise construct a dummy one
|
||||
@@ -173,6 +173,9 @@ impl<R> OutQueueControl<R>
|
||||
where
|
||||
R: CryptoRng + Rng + Unpin,
|
||||
{
|
||||
// at this point I'm not entirely sure how to deal with this warning without
|
||||
// some considerable refactoring
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub(crate) fn new(
|
||||
config: Config,
|
||||
ack_key: Arc<AckKey>,
|
||||
|
||||
@@ -129,6 +129,12 @@ impl TopologyAccessor {
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for TopologyAccessor {
|
||||
fn default() -> Self {
|
||||
TopologyAccessor::new()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TopologyRefresherConfig {
|
||||
directory_server: String,
|
||||
refresh_rate: time::Duration,
|
||||
|
||||
@@ -305,7 +305,7 @@ impl<T: NymConfig> Config<T> {
|
||||
true => Some(
|
||||
self.debug
|
||||
.vpn_key_reuse_limit
|
||||
.unwrap_or_else(|| DEFAULT_VPN_KEY_REUSE_LIMIT),
|
||||
.unwrap_or(DEFAULT_VPN_KEY_REUSE_LIMIT),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -206,11 +206,11 @@ impl ClientRequest {
|
||||
}
|
||||
|
||||
// SELF_ADDRESS_REQUEST_TAG
|
||||
fn deserialize_self_address(b: &[u8]) -> Result<Self, error::Error> {
|
||||
fn deserialize_self_address(b: &[u8]) -> Self {
|
||||
// this MUST match because it was called by 'deserialize'
|
||||
debug_assert_eq!(b[0], SELF_ADDRESS_REQUEST_TAG);
|
||||
|
||||
Ok(ClientRequest::SelfAddress)
|
||||
ClientRequest::SelfAddress
|
||||
}
|
||||
|
||||
pub fn serialize(self) -> Vec<u8> {
|
||||
@@ -255,7 +255,7 @@ impl ClientRequest {
|
||||
match request_tag {
|
||||
SEND_REQUEST_TAG => Self::deserialize_send(b),
|
||||
REPLY_REQUEST_TAG => Self::deserialize_reply(b),
|
||||
SELF_ADDRESS_REQUEST_TAG => Self::deserialize_self_address(b),
|
||||
SELF_ADDRESS_REQUEST_TAG => Ok(Self::deserialize_self_address(b)),
|
||||
n => Err(error::Error::new(
|
||||
ErrorKind::UnknownRequest,
|
||||
format!("type {}", n),
|
||||
|
||||
@@ -115,15 +115,15 @@ impl TryFrom<String> for ServerResponseText {
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<String> for ServerResponseText {
|
||||
fn into(self) -> String {
|
||||
impl From<ServerResponseText> for String {
|
||||
fn from(res: ServerResponseText) -> Self {
|
||||
// per serde_json docs:
|
||||
/*
|
||||
/// Serialization can fail if `T`'s implementation of `Serialize` decides to
|
||||
/// fail, or if `T` contains a map with non-string keys.
|
||||
*/
|
||||
// this is not the case here.
|
||||
serde_json::to_string(&self).unwrap()
|
||||
serde_json::to_string(&res).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -220,14 +220,9 @@ impl SocksClient {
|
||||
}
|
||||
|
||||
async fn send_connect_to_mixnet(&mut self, remote_address: RemoteAddress) {
|
||||
let req = Request::new_connect(
|
||||
self.connection_id,
|
||||
remote_address.clone(),
|
||||
self.self_address.clone(),
|
||||
);
|
||||
let req = Request::new_connect(self.connection_id, remote_address, self.self_address);
|
||||
|
||||
let input_message =
|
||||
InputMessage::new_fresh(self.service_provider.clone(), req.into_bytes(), false);
|
||||
let input_message = InputMessage::new_fresh(self.service_provider, req.into_bytes(), false);
|
||||
self.input_sender.unbounded_send(input_message).unwrap();
|
||||
}
|
||||
|
||||
|
||||
@@ -31,8 +31,6 @@ use wasm_utils::{console_log, console_warn};
|
||||
|
||||
pub(crate) mod received_processor;
|
||||
|
||||
const DEFAULT_RNG: OsRng = OsRng;
|
||||
|
||||
const DEFAULT_AVERAGE_PACKET_DELAY: Duration = Duration::from_millis(200);
|
||||
const DEFAULT_AVERAGE_ACK_DELAY: Duration = Duration::from_millis(200);
|
||||
const DEFAULT_GATEWAY_RESPONSE_TIMEOUT: Duration = Duration::from_millis(1_500);
|
||||
@@ -67,10 +65,11 @@ pub struct NymClient {
|
||||
impl NymClient {
|
||||
#[wasm_bindgen(constructor)]
|
||||
pub fn new(validator_server: String) -> Self {
|
||||
let mut rng = OsRng;
|
||||
// for time being generate new keys each time...
|
||||
let identity = identity::KeyPair::new_with_rng(&mut DEFAULT_RNG);
|
||||
let encryption_keys = encryption::KeyPair::new_with_rng(&mut DEFAULT_RNG);
|
||||
let ack_key = AckKey::new(&mut DEFAULT_RNG);
|
||||
let identity = identity::KeyPair::new_with_rng(&mut rng);
|
||||
let encryption_keys = encryption::KeyPair::new_with_rng(&mut rng);
|
||||
let ack_key = AckKey::new(&mut rng);
|
||||
|
||||
Self {
|
||||
identity: Arc::new(identity),
|
||||
@@ -145,7 +144,7 @@ impl NymClient {
|
||||
};
|
||||
|
||||
let message_preparer = MessagePreparer::new(
|
||||
DEFAULT_RNG,
|
||||
&mut rand::rngs::OsRng,
|
||||
client.self_recipient(),
|
||||
DEFAULT_AVERAGE_PACKET_DELAY,
|
||||
DEFAULT_AVERAGE_ACK_DELAY,
|
||||
|
||||
@@ -11,6 +11,7 @@ edition = "2018"
|
||||
# the entire crate
|
||||
futures = "0.3"
|
||||
log = "0.4"
|
||||
rand = { version = "0.7.3", features = ["wasm-bindgen"] }
|
||||
|
||||
# internal
|
||||
crypto = { path = "../../crypto" }
|
||||
|
||||
@@ -23,10 +23,11 @@ use crypto::asymmetric::identity;
|
||||
use futures::{FutureExt, SinkExt, StreamExt};
|
||||
use gateway_requests::authentication::encrypted_address::EncryptedAddressBytes;
|
||||
use gateway_requests::authentication::iv::AuthenticationIV;
|
||||
use gateway_requests::registration::handshake::{client_handshake, SharedKeys, DEFAULT_RNG};
|
||||
use gateway_requests::registration::handshake::{client_handshake, SharedKeys};
|
||||
use gateway_requests::{BinaryRequest, ClientControlRequest, ServerResponse};
|
||||
use log::*;
|
||||
use nymsphinx::forwarding::packet::MixPacket;
|
||||
use rand::rngs::OsRng;
|
||||
use std::convert::TryFrom;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
@@ -178,7 +179,7 @@ impl GatewayClient {
|
||||
|
||||
for i in 1..self.reconnection_attempts {
|
||||
info!("attempt {}...", i);
|
||||
if let Ok(_) = self.authenticate_and_start().await {
|
||||
if self.authenticate_and_start().await.is_ok() {
|
||||
info!("managed to reconnect!");
|
||||
return Ok(());
|
||||
}
|
||||
@@ -339,9 +340,13 @@ impl GatewayClient {
|
||||
|
||||
debug_assert!(self.connection.is_available());
|
||||
|
||||
// it's fine to instantiate it here as it's only used once (during authentication or registration)
|
||||
// and putting it into the GatewayClient struct would be a hassle
|
||||
let mut rng = OsRng;
|
||||
|
||||
let shared_key = match &mut self.connection {
|
||||
SocketState::Available(ws_stream) => client_handshake(
|
||||
&mut DEFAULT_RNG,
|
||||
&mut rng,
|
||||
ws_stream,
|
||||
self.local_identity.as_ref(),
|
||||
self.gateway_identity,
|
||||
@@ -365,11 +370,16 @@ impl GatewayClient {
|
||||
if !self.connection.is_established() {
|
||||
return Err(GatewayClientError::ConnectionNotEstablished);
|
||||
}
|
||||
|
||||
// it's fine to instantiate it here as it's only used once (during authentication or registration)
|
||||
// and putting it into the GatewayClient struct would be a hassle
|
||||
let mut rng = OsRng;
|
||||
|
||||
// because of the previous check one of the unwraps MUST succeed
|
||||
let shared_key = shared_key
|
||||
.as_ref()
|
||||
.unwrap_or_else(|| self.shared_key.as_ref().unwrap());
|
||||
let iv = AuthenticationIV::new_random(&mut DEFAULT_RNG);
|
||||
let iv = AuthenticationIV::new_random(&mut rng);
|
||||
let self_address = self
|
||||
.local_identity
|
||||
.as_ref()
|
||||
@@ -516,7 +526,7 @@ impl GatewayClient {
|
||||
.as_ref()
|
||||
.expect("no shared key present even though we're authenticated!"),
|
||||
),
|
||||
)?
|
||||
)
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
@@ -50,12 +50,12 @@ impl GatewayClientError {
|
||||
match self {
|
||||
GatewayClientError::NetworkError(ws_err) => match ws_err {
|
||||
WsError::AlreadyClosed | WsError::ConnectionClosed => true,
|
||||
WsError::Io(io_err) => match io_err.kind() {
|
||||
WsError::Io(io_err) => matches!(
|
||||
io_err.kind(),
|
||||
io::ErrorKind::ConnectionReset
|
||||
| io::ErrorKind::ConnectionAborted
|
||||
| io::ErrorKind::BrokenPipe => true,
|
||||
_ => false,
|
||||
},
|
||||
| io::ErrorKind::ConnectionAborted
|
||||
| io::ErrorKind::BrokenPipe
|
||||
),
|
||||
_ => false,
|
||||
},
|
||||
_ => false,
|
||||
|
||||
@@ -97,7 +97,7 @@ impl PartiallyDelegated {
|
||||
conn: WsConn,
|
||||
packet_router: PacketRouter,
|
||||
shared_key: Arc<SharedKeys>,
|
||||
) -> Result<Self, GatewayClientError> {
|
||||
) -> Self {
|
||||
// when called for, it NEEDS TO yield back the stream so that we could merge it and
|
||||
// read control request responses.
|
||||
let (notify_sender, notify_receiver) = oneshot::channel();
|
||||
@@ -137,10 +137,10 @@ impl PartiallyDelegated {
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
tokio::spawn(mixnet_receiver_future);
|
||||
|
||||
Ok(PartiallyDelegated {
|
||||
PartiallyDelegated {
|
||||
sink_half: sink,
|
||||
delegated_stream: (stream_receiver, notify_sender),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// if we want to send a message and don't care about response, we can don't need to reunite the split,
|
||||
@@ -181,7 +181,7 @@ impl PartiallyDelegated {
|
||||
// this call failing is incredibly unlikely, but not impossible.
|
||||
// basically the gateway connection must have failed after executing previous line but
|
||||
// before starting execution of this one.
|
||||
if let Err(_) = notify.send(()) {
|
||||
if notify.send(()).is_err() {
|
||||
return Err(GatewayClientError::ConnectionAbruptlyClosed);
|
||||
}
|
||||
|
||||
@@ -212,6 +212,9 @@ impl SocketState {
|
||||
}
|
||||
|
||||
pub(crate) fn is_established(&self) -> bool {
|
||||
matches!(self, SocketState::Available(_) | SocketState::PartiallyDelegated(_))
|
||||
matches!(
|
||||
self,
|
||||
SocketState::Available(_) | SocketState::PartiallyDelegated(_)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,7 +144,7 @@ impl Client {
|
||||
self.config
|
||||
.initial_reconnection_backoff
|
||||
.checked_mul(2_u32.pow(current_attempt))
|
||||
.unwrap_or_else(|| self.config.maximum_reconnection_backoff),
|
||||
.unwrap_or(self.config.maximum_reconnection_backoff),
|
||||
self.config.maximum_reconnection_backoff,
|
||||
),
|
||||
))
|
||||
|
||||
@@ -31,12 +31,12 @@ pub struct Topology {
|
||||
|
||||
// changed from `TryInto`. reason being is that we should not fail entire topology
|
||||
// conversion if there's one invalid node on the network screwing around
|
||||
impl Into<NymTopology> for Topology {
|
||||
fn into(self) -> NymTopology {
|
||||
impl From<Topology> for NymTopology {
|
||||
fn from(topology: Topology) -> Self {
|
||||
use std::collections::HashMap;
|
||||
|
||||
let mut mixes = HashMap::new();
|
||||
for mix in self.mix_nodes.into_iter() {
|
||||
for mix in topology.mix_nodes.into_iter() {
|
||||
let layer = mix.mix_info.layer as MixLayer;
|
||||
if layer == 0 || layer > 3 {
|
||||
warn!(
|
||||
@@ -57,8 +57,8 @@ impl Into<NymTopology> for Topology {
|
||||
}
|
||||
}
|
||||
|
||||
let mut gateways = Vec::with_capacity(self.gateways.len());
|
||||
for gate in self.gateways.into_iter() {
|
||||
let mut gateways = Vec::with_capacity(topology.gateways.len());
|
||||
for gate in topology.gateways.into_iter() {
|
||||
let gate_id = gate.gateway_info.node_info.identity_key.clone();
|
||||
match gate.try_into() {
|
||||
Ok(gate) => gateways.push(gate),
|
||||
|
||||
@@ -35,7 +35,7 @@ impl RESTRequest for Request {
|
||||
_: Option<Vec<QueryParam>>,
|
||||
body_payload: Option<Self::JsonPayload>,
|
||||
) -> Result<Self, RESTRequestError> {
|
||||
let payload = body_payload.ok_or_else(|| RESTRequestError::NoPayloadProvided)?;
|
||||
let payload = body_payload.ok_or(RESTRequestError::NoPayloadProvided)?;
|
||||
let url = Url::parse(&format!("{}{}", base_url, Self::RELATIVE_PATH))
|
||||
.map_err(|err| RESTRequestError::MalformedUrl(err.to_string()))?;
|
||||
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ impl RESTRequest for Request {
|
||||
_: Option<Vec<QueryParam>>,
|
||||
body_payload: Option<Self::JsonPayload>,
|
||||
) -> Result<Self, RESTRequestError> {
|
||||
let payload = body_payload.ok_or_else(|| RESTRequestError::NoPayloadProvided)?;
|
||||
let payload = body_payload.ok_or(RESTRequestError::NoPayloadProvided)?;
|
||||
let url = Url::parse(&format!("{}{}", base_url, Self::RELATIVE_PATH))
|
||||
.map_err(|err| RESTRequestError::MalformedUrl(err.to_string()))?;
|
||||
Ok(Request { url, payload })
|
||||
|
||||
@@ -20,7 +20,7 @@ impl RESTRequest for Request {
|
||||
_: Option<Vec<QueryParam>>,
|
||||
body_payload: Option<Self::JsonPayload>,
|
||||
) -> Result<Self, RESTRequestError> {
|
||||
let payload = body_payload.ok_or_else(|| RESTRequestError::NoPayloadProvided)?;
|
||||
let payload = body_payload.ok_or(RESTRequestError::NoPayloadProvided)?;
|
||||
let url = Url::parse(&format!("{}{}", base_url, Self::RELATIVE_PATH))
|
||||
.map_err(|err| RESTRequestError::MalformedUrl(err.to_string()))?;
|
||||
Ok(Request { url, payload })
|
||||
|
||||
@@ -35,7 +35,7 @@ impl RESTRequest for Request {
|
||||
_: Option<Vec<QueryParam>>,
|
||||
body_payload: Option<Self::JsonPayload>,
|
||||
) -> Result<Self, RESTRequestError> {
|
||||
let payload = body_payload.ok_or_else(|| RESTRequestError::NoPayloadProvided)?;
|
||||
let payload = body_payload.ok_or(RESTRequestError::NoPayloadProvided)?;
|
||||
let url = Url::parse(&format!("{}{}", base_url, Self::RELATIVE_PATH))
|
||||
.map_err(|err| RESTRequestError::MalformedUrl(err.to_string()))?;
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ impl RESTRequest for Request {
|
||||
_: Option<Self::JsonPayload>,
|
||||
) -> Result<Self, RESTRequestError> {
|
||||
// node unregister requires single path param - the node id
|
||||
let path_params = path_params.ok_or_else(|| RESTRequestError::InvalidPathParams)?;
|
||||
let path_params = path_params.ok_or(RESTRequestError::InvalidPathParams)?;
|
||||
if path_params.len() != 1 {
|
||||
return Err(RESTRequestError::InvalidPathParams);
|
||||
}
|
||||
|
||||
@@ -34,12 +34,12 @@ impl RESTRequest for Request {
|
||||
) -> Result<Self, RESTRequestError> {
|
||||
// set reputation requires single path param - the node id
|
||||
// and single query param - what reputation should it be set to
|
||||
let path_params = path_params.ok_or_else(|| RESTRequestError::InvalidPathParams)?;
|
||||
let path_params = path_params.ok_or(RESTRequestError::InvalidPathParams)?;
|
||||
if path_params.len() != 1 {
|
||||
return Err(RESTRequestError::InvalidPathParams);
|
||||
}
|
||||
|
||||
let query_params = query_params.ok_or_else(|| RESTRequestError::InvalidQueryParams)?;
|
||||
let query_params = query_params.ok_or(RESTRequestError::InvalidQueryParams)?;
|
||||
if query_params.len() != 1 {
|
||||
return Err(RESTRequestError::InvalidQueryParams);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
use pemstore::traits::{PemStorableKey, PemStorableKeyPair};
|
||||
use rand::{rngs::OsRng, CryptoRng, RngCore};
|
||||
use rand::{CryptoRng, RngCore};
|
||||
use std::fmt::{self, Display, Formatter};
|
||||
|
||||
/// Size of a X25519 private key
|
||||
@@ -57,12 +57,7 @@ pub struct KeyPair {
|
||||
}
|
||||
|
||||
impl KeyPair {
|
||||
pub fn new() -> Self {
|
||||
let mut rng = OsRng;
|
||||
Self::new_with_rng(&mut rng)
|
||||
}
|
||||
|
||||
pub fn new_with_rng<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
|
||||
pub fn new<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
|
||||
let private_key = x25519_dalek::StaticSecret::new(rng);
|
||||
let public_key = (&private_key).into();
|
||||
|
||||
@@ -206,16 +201,15 @@ impl PemStorableKey for PrivateKey {
|
||||
}
|
||||
|
||||
// compatibility with sphinx keys:
|
||||
|
||||
impl Into<nymsphinx_types::PublicKey> for PublicKey {
|
||||
fn into(self) -> nymsphinx_types::PublicKey {
|
||||
nymsphinx_types::PublicKey::from(self.to_bytes())
|
||||
impl From<PublicKey> for nymsphinx_types::PublicKey {
|
||||
fn from(key: PublicKey) -> Self {
|
||||
nymsphinx_types::PublicKey::from(key.to_bytes())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Into<nymsphinx_types::PublicKey> for &'a PublicKey {
|
||||
fn into(self) -> nymsphinx_types::PublicKey {
|
||||
nymsphinx_types::PublicKey::from(self.to_bytes())
|
||||
impl<'a> From<&'a PublicKey> for nymsphinx_types::PublicKey {
|
||||
fn from(key: &'a PublicKey) -> Self {
|
||||
nymsphinx_types::PublicKey::from(key.to_bytes())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,15 +219,15 @@ impl From<nymsphinx_types::PublicKey> for PublicKey {
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<nymsphinx_types::PrivateKey> for PrivateKey {
|
||||
fn into(self) -> nymsphinx_types::PrivateKey {
|
||||
nymsphinx_types::PrivateKey::from(self.to_bytes())
|
||||
impl From<PrivateKey> for nymsphinx_types::PrivateKey {
|
||||
fn from(key: PrivateKey) -> Self {
|
||||
nymsphinx_types::PrivateKey::from(key.to_bytes())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Into<nymsphinx_types::PrivateKey> for &'a PrivateKey {
|
||||
fn into(self) -> nymsphinx_types::PrivateKey {
|
||||
nymsphinx_types::PrivateKey::from(self.to_bytes())
|
||||
impl<'a> From<&'a PrivateKey> for nymsphinx_types::PrivateKey {
|
||||
fn from(key: &'a PrivateKey) -> Self {
|
||||
nymsphinx_types::PrivateKey::from(key.to_bytes())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -253,8 +247,10 @@ mod sphinx_key_conversion {
|
||||
|
||||
#[test]
|
||||
fn works_for_forward_conversion() {
|
||||
let mut rng = rand::rngs::OsRng;
|
||||
|
||||
for _ in 0..NUM_ITERATIONS {
|
||||
let keys = KeyPair::new();
|
||||
let keys = KeyPair::new(&mut rng);
|
||||
let private = keys.private_key;
|
||||
let public = keys.public_key;
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ pub use ed25519_dalek::SignatureError;
|
||||
pub use ed25519_dalek::{Verifier, PUBLIC_KEY_LENGTH, SECRET_KEY_LENGTH, SIGNATURE_LENGTH};
|
||||
use nymsphinx_types::{DestinationAddressBytes, DESTINATION_ADDRESS_LENGTH};
|
||||
use pemstore::traits::{PemStorableKey, PemStorableKeyPair};
|
||||
use rand::{rngs::OsRng, CryptoRng, RngCore};
|
||||
use rand::{CryptoRng, RngCore};
|
||||
use std::fmt::{self, Formatter};
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -56,12 +56,7 @@ pub struct KeyPair {
|
||||
}
|
||||
|
||||
impl KeyPair {
|
||||
pub fn new() -> Self {
|
||||
let mut rng = OsRng;
|
||||
Self::new_with_rng(&mut rng)
|
||||
}
|
||||
|
||||
pub fn new_with_rng<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
|
||||
pub fn new<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
|
||||
let ed25519_keypair = ed25519_dalek::Keypair::generate(rng);
|
||||
|
||||
KeyPair {
|
||||
|
||||
@@ -32,7 +32,7 @@ where
|
||||
D::OutputSize: ArrayLength<u8>,
|
||||
R: RngCore + CryptoRng,
|
||||
{
|
||||
let ephemeral_keypair = encryption::KeyPair::new_with_rng(rng);
|
||||
let ephemeral_keypair = encryption::KeyPair::new(rng);
|
||||
|
||||
// after performing diffie-hellman we don't care about the private component anymore
|
||||
let dh_result = ephemeral_keypair.private_key().diffie_hellman(remote_key);
|
||||
|
||||
@@ -61,6 +61,12 @@ impl<T> NonExhaustiveDelayQueue<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Default for NonExhaustiveDelayQueue<T> {
|
||||
fn default() -> Self {
|
||||
NonExhaustiveDelayQueue::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Stream for NonExhaustiveDelayQueue<T> {
|
||||
type Item = <DelayQueue<T> as Stream>::Item;
|
||||
|
||||
|
||||
@@ -10,3 +10,6 @@ edition = "2018"
|
||||
crypto = { path = "../../crypto" } # all addresses are expressed in terms on their crypto keys
|
||||
nymsphinx-types = { path = "../types" } # we need to be able to refer to some types defined inside sphinx crate
|
||||
serde = "1.0" # implementing serialization/deserialization for some types, like `Recipient`
|
||||
|
||||
[dev-dependencies]
|
||||
rand = "0.7"
|
||||
@@ -245,9 +245,11 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn string_conversion_works() {
|
||||
let client_id_pair = identity::KeyPair::new();
|
||||
let client_enc_pair = encryption::KeyPair::new();
|
||||
let gateway_id_pair = identity::KeyPair::new();
|
||||
let mut rng = rand::thread_rng();
|
||||
|
||||
let client_id_pair = identity::KeyPair::new(&mut rng);
|
||||
let client_enc_pair = encryption::KeyPair::new(&mut rng);
|
||||
let gateway_id_pair = identity::KeyPair::new(&mut rng);
|
||||
|
||||
let recipient = Recipient::new(
|
||||
*client_id_pair.public_key(),
|
||||
@@ -275,9 +277,11 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn bytes_conversion_works() {
|
||||
let client_id_pair = identity::KeyPair::new();
|
||||
let client_enc_pair = encryption::KeyPair::new();
|
||||
let gateway_id_pair = identity::KeyPair::new();
|
||||
let mut rng = rand::thread_rng();
|
||||
|
||||
let client_id_pair = identity::KeyPair::new(&mut rng);
|
||||
let client_enc_pair = encryption::KeyPair::new(&mut rng);
|
||||
let gateway_id_pair = identity::KeyPair::new(&mut rng);
|
||||
|
||||
let recipient = Recipient::new(
|
||||
*client_id_pair.public_key(),
|
||||
|
||||
@@ -139,9 +139,9 @@ impl From<SocketAddr> for NymNodeRoutingAddress {
|
||||
|
||||
/// Considering `NymNodeRoutingAddress` is equivalent to a `SocketAddr` at this point,
|
||||
/// it makes perfect sense to allow the bilateral transformation.
|
||||
impl Into<SocketAddr> for NymNodeRoutingAddress {
|
||||
fn into(self) -> SocketAddr {
|
||||
self.0
|
||||
impl From<NymNodeRoutingAddress> for SocketAddr {
|
||||
fn from(addr: NymNodeRoutingAddress) -> Self {
|
||||
addr.0
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -169,25 +169,19 @@ impl Fragment {
|
||||
if payload.len() != linked_fragment_payload_max_len(max_plaintext_size) {
|
||||
return Err(ChunkingError::InvalidPayloadLengthError);
|
||||
}
|
||||
} else {
|
||||
if payload.len() > linked_fragment_payload_max_len(max_plaintext_size) {
|
||||
return Err(ChunkingError::InvalidPayloadLengthError);
|
||||
}
|
||||
} else if payload.len() > linked_fragment_payload_max_len(max_plaintext_size) {
|
||||
return Err(ChunkingError::InvalidPayloadLengthError);
|
||||
}
|
||||
} else if next_fragments_set_id.is_some() {
|
||||
if payload.len() != linked_fragment_payload_max_len(max_plaintext_size) {
|
||||
return Err(ChunkingError::InvalidPayloadLengthError);
|
||||
}
|
||||
} else {
|
||||
if total_fragments != current_fragment {
|
||||
if payload.len() != unlinked_fragment_payload_max_len(max_plaintext_size) {
|
||||
return Err(ChunkingError::InvalidPayloadLengthError);
|
||||
}
|
||||
} else {
|
||||
if payload.len() > unlinked_fragment_payload_max_len(max_plaintext_size) {
|
||||
return Err(ChunkingError::InvalidPayloadLengthError);
|
||||
}
|
||||
} else if total_fragments != current_fragment {
|
||||
if payload.len() != unlinked_fragment_payload_max_len(max_plaintext_size) {
|
||||
return Err(ChunkingError::InvalidPayloadLengthError);
|
||||
}
|
||||
} else if payload.len() > unlinked_fragment_payload_max_len(max_plaintext_size) {
|
||||
return Err(ChunkingError::InvalidPayloadLengthError);
|
||||
}
|
||||
|
||||
Ok(Fragment {
|
||||
@@ -453,7 +447,7 @@ impl FragmentHeader {
|
||||
// everything below are tests
|
||||
|
||||
#[cfg(test)]
|
||||
mod fragment {
|
||||
mod fragment_tests {
|
||||
use super::*;
|
||||
use nymsphinx_params::packet_sizes::PacketSize;
|
||||
use rand::{thread_rng, RngCore};
|
||||
@@ -952,7 +946,7 @@ mod fragment_header {
|
||||
// clear the fragmentation flag
|
||||
header_bytes_low[0] &= !(1 << 7);
|
||||
|
||||
let mut header_bytes_high = header_bytes_low.clone();
|
||||
let mut header_bytes_high = header_bytes_low;
|
||||
// make sure first byte of id is non-empty (apart from the fragmentation flag)
|
||||
// note for anyone reading this test in the future: choice of '3' here is arbitrary.
|
||||
header_bytes_high[0] |= 1 << 3;
|
||||
|
||||
@@ -115,21 +115,21 @@ pub fn number_of_required_fragments(
|
||||
|
||||
// we must be careful with the last set as it might be the case that it only
|
||||
// consists of a single, linked, non-full fragment
|
||||
if final_set_message_len < max_linked {
|
||||
return (without_last + 1, max_linked - final_set_message_len);
|
||||
} else if final_set_message_len == max_linked {
|
||||
return (without_last + 1, 0);
|
||||
}
|
||||
match final_set_message_len {
|
||||
n if n < max_linked => (without_last + 1, max_linked - final_set_message_len),
|
||||
n if n == max_linked => (without_last + 1, 0),
|
||||
_ => {
|
||||
let remaining_len = final_set_message_len - max_linked;
|
||||
|
||||
let remaining_len = final_set_message_len - max_linked;
|
||||
let quot = remaining_len / max_unlinked;
|
||||
let rem = remaining_len % max_unlinked;
|
||||
|
||||
let quot = remaining_len / max_unlinked;
|
||||
let rem = remaining_len % max_unlinked;
|
||||
|
||||
if rem == 0 {
|
||||
(without_last + quot + 1, 0)
|
||||
} else {
|
||||
(without_last + quot + 2, max_unlinked - rem)
|
||||
if rem == 0 {
|
||||
(without_last + quot + 1, 0)
|
||||
} else {
|
||||
(without_last + quot + 2, max_unlinked - rem)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -456,8 +456,9 @@ mod reconstruction_buffer {
|
||||
.flat_map(|fragment_set| fragment_set.into_iter())
|
||||
.map(|x| x.into_bytes())
|
||||
.collect();
|
||||
for i in 0..254 {
|
||||
buf.insert_fragment(Fragment::try_from_bytes(&raw_fragments[i]).unwrap());
|
||||
|
||||
for raw_fragment in raw_fragments.iter().take(u8::max_value() as usize - 1) {
|
||||
buf.insert_fragment(Fragment::try_from_bytes(&raw_fragment).unwrap());
|
||||
}
|
||||
|
||||
assert!(!buf.is_complete);
|
||||
@@ -536,12 +537,13 @@ mod message_reconstructor {
|
||||
.flat_map(|fragment_set| fragment_set.into_iter())
|
||||
.map(|x| x.into_bytes())
|
||||
.collect();
|
||||
|
||||
// first set is fully inserted
|
||||
for i in 0..255 {
|
||||
for raw_fragment in raw_fragments.iter() {
|
||||
assert!(reconstructor
|
||||
.insert_new_fragment(
|
||||
reconstructor
|
||||
.recover_fragment(raw_fragments[i].clone())
|
||||
.recover_fragment(raw_fragment.clone())
|
||||
.unwrap()
|
||||
)
|
||||
.is_none())
|
||||
@@ -572,15 +574,17 @@ mod message_reconstructor {
|
||||
.flat_map(|fragment_set| fragment_set.into_iter())
|
||||
.map(|x| x.into_bytes())
|
||||
.collect();
|
||||
for i in 0..254 {
|
||||
|
||||
for raw_fragment in raw_fragments.iter().take(u8::max_value() as usize) {
|
||||
assert!(reconstructor
|
||||
.insert_new_fragment(
|
||||
reconstructor
|
||||
.recover_fragment(raw_fragments[i].clone())
|
||||
.recover_fragment(raw_fragment.clone())
|
||||
.unwrap()
|
||||
)
|
||||
.is_none());
|
||||
}
|
||||
|
||||
// finish next set for good measure
|
||||
assert!(reconstructor
|
||||
.insert_new_fragment(
|
||||
@@ -619,11 +623,11 @@ mod message_reconstructor {
|
||||
.collect();
|
||||
|
||||
// note that first set is not fully inserted
|
||||
for i in 0..254 {
|
||||
for raw_fragment in raw_fragments.iter().take(u8::max_value() as usize - 1) {
|
||||
assert!(reconstructor
|
||||
.insert_new_fragment(
|
||||
reconstructor
|
||||
.recover_fragment(raw_fragments[i].clone())
|
||||
.recover_fragment(raw_fragment.clone())
|
||||
.unwrap()
|
||||
)
|
||||
.is_none());
|
||||
@@ -664,11 +668,12 @@ mod message_reconstructor {
|
||||
.flat_map(|fragment_set| fragment_set.into_iter())
|
||||
.map(|x| x.into_bytes())
|
||||
.collect();
|
||||
for i in 0..255 {
|
||||
|
||||
for raw_fragment in raw_fragments.iter().take(u8::max_value() as usize) {
|
||||
assert!(reconstructor
|
||||
.insert_new_fragment(
|
||||
reconstructor
|
||||
.recover_fragment(raw_fragments[i].clone())
|
||||
.recover_fragment(raw_fragment.clone())
|
||||
.unwrap()
|
||||
)
|
||||
.is_none());
|
||||
@@ -705,11 +710,12 @@ mod message_reconstructor {
|
||||
.flat_map(|fragment_set| fragment_set.into_iter())
|
||||
.map(|x| x.into_bytes())
|
||||
.collect();
|
||||
for i in 0..255 {
|
||||
|
||||
for raw_fragment in raw_fragments.iter().take(u8::max_value() as usize) {
|
||||
assert!(reconstructor
|
||||
.insert_new_fragment(
|
||||
reconstructor
|
||||
.recover_fragment(raw_fragments[i].clone())
|
||||
.recover_fragment(raw_fragment.clone())
|
||||
.unwrap()
|
||||
)
|
||||
.is_none());
|
||||
@@ -744,11 +750,11 @@ mod message_reconstructor {
|
||||
.collect();
|
||||
|
||||
// note that first set is not fully inserted
|
||||
for i in 0..254 {
|
||||
for raw_fragment in raw_fragments.iter().take(u8::max_value() as usize - 1) {
|
||||
assert!(reconstructor
|
||||
.insert_new_fragment(
|
||||
reconstructor
|
||||
.recover_fragment(raw_fragments[i].clone())
|
||||
.recover_fragment(raw_fragment.clone())
|
||||
.unwrap()
|
||||
)
|
||||
.is_none());
|
||||
@@ -784,11 +790,12 @@ mod message_reconstructor {
|
||||
.flat_map(|fragment_set| fragment_set.into_iter())
|
||||
.map(|x| x.into_bytes())
|
||||
.collect();
|
||||
for i in 0..(u8::max_value() as usize) * 2 {
|
||||
|
||||
for raw_fragment in raw_fragments.iter().take(u8::max_value() as usize * 2) {
|
||||
assert!(reconstructor
|
||||
.insert_new_fragment(
|
||||
reconstructor
|
||||
.recover_fragment(raw_fragments[i].clone())
|
||||
.recover_fragment(raw_fragment.clone())
|
||||
.unwrap()
|
||||
)
|
||||
.is_none());
|
||||
@@ -825,12 +832,17 @@ mod message_reconstructor {
|
||||
.flat_map(|fragment_set| fragment_set.into_iter())
|
||||
.map(|x| x.into_bytes())
|
||||
.collect();
|
||||
|
||||
// note that first set is not fully inserted
|
||||
for i in 1..(u8::max_value() as usize) * 2 {
|
||||
for raw_fragment in raw_fragments
|
||||
.iter()
|
||||
.skip(1)
|
||||
.take(u8::max_value() as usize * 2 - 1)
|
||||
{
|
||||
assert!(reconstructor
|
||||
.insert_new_fragment(
|
||||
reconstructor
|
||||
.recover_fragment(raw_fragments[i].clone())
|
||||
.recover_fragment(raw_fragment.clone())
|
||||
.unwrap()
|
||||
)
|
||||
.is_none());
|
||||
@@ -896,11 +908,11 @@ mod message_reconstructor {
|
||||
.collect();
|
||||
|
||||
// note that first set is not fully inserted
|
||||
for i in 0..254 {
|
||||
for raw_fragment in raw_fragments1.iter().take(u8::max_value() as usize - 1) {
|
||||
assert!(reconstructor
|
||||
.insert_new_fragment(
|
||||
reconstructor
|
||||
.recover_fragment(raw_fragments1[i].clone())
|
||||
.recover_fragment(raw_fragment.clone())
|
||||
.unwrap()
|
||||
)
|
||||
.is_none());
|
||||
@@ -930,11 +942,11 @@ mod message_reconstructor {
|
||||
.map(|x| x.into_bytes())
|
||||
.collect();
|
||||
|
||||
for i in 0..255 {
|
||||
for raw_fragment in raw_fragments2.iter().take(u8::max_value() as usize) {
|
||||
assert!(reconstructor
|
||||
.insert_new_fragment(
|
||||
reconstructor
|
||||
.recover_fragment(raw_fragments2[i].clone())
|
||||
.recover_fragment(raw_fragment.clone())
|
||||
.unwrap()
|
||||
)
|
||||
.is_none());
|
||||
@@ -969,11 +981,12 @@ mod message_reconstructor {
|
||||
.flat_map(|fragment_set| fragment_set.into_iter())
|
||||
.map(|x| x.into_bytes())
|
||||
.collect();
|
||||
for i in 0..255 {
|
||||
|
||||
for raw_fragment in raw_fragments.iter().take(u8::max_value() as usize) {
|
||||
assert!(reconstructor
|
||||
.insert_new_fragment(
|
||||
reconstructor
|
||||
.recover_fragment(raw_fragments[i].clone())
|
||||
.recover_fragment(raw_fragment.clone())
|
||||
.unwrap()
|
||||
)
|
||||
.is_none());
|
||||
@@ -1265,8 +1278,9 @@ mod message_reconstructor {
|
||||
.flat_map(|fragment_set| fragment_set.into_iter())
|
||||
.map(|x| x.into_bytes())
|
||||
.collect();
|
||||
for i in 0..255 {
|
||||
set_buf1.insert_fragment(Fragment::try_from_bytes(&raw_fragments[i]).unwrap());
|
||||
|
||||
for raw_fragment in raw_fragments.iter().take(u8::max_value() as usize) {
|
||||
set_buf1.insert_fragment(Fragment::try_from_bytes(&raw_fragment).unwrap());
|
||||
}
|
||||
|
||||
set_buf2.insert_fragment(Fragment::try_from_bytes(&raw_fragments[255]).unwrap());
|
||||
@@ -1496,11 +1510,12 @@ mod message_reconstruction {
|
||||
assert_eq!(fragments.len(), 30);
|
||||
|
||||
let mut message_reconstructor = MessageReconstructor::default();
|
||||
for i in 0..29 {
|
||||
|
||||
for fragment in fragments.iter().take(fragments.len() - 1) {
|
||||
assert!(message_reconstructor
|
||||
.insert_new_fragment(
|
||||
message_reconstructor
|
||||
.recover_fragment(fragments[i].clone())
|
||||
.recover_fragment(fragment.clone())
|
||||
.unwrap()
|
||||
)
|
||||
.is_none());
|
||||
@@ -1538,11 +1553,11 @@ mod message_reconstruction {
|
||||
fragments.shuffle(&mut rng);
|
||||
|
||||
let mut message_reconstructor = MessageReconstructor::default();
|
||||
for i in 0..29 {
|
||||
for fragment in fragments.iter().take(fragments.len() - 1) {
|
||||
assert!(message_reconstructor
|
||||
.insert_new_fragment(
|
||||
message_reconstructor
|
||||
.recover_fragment(fragments[i].clone())
|
||||
.recover_fragment(fragment.clone())
|
||||
.unwrap()
|
||||
)
|
||||
.is_none());
|
||||
|
||||
@@ -389,7 +389,7 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
fn verify_correct_link(left: &FragmentSet, right: &FragmentSet) {
|
||||
fn verify_correct_link(left: &[Fragment], right: &[Fragment]) {
|
||||
let first_id = left[0].id();
|
||||
let post_id = left[254].next_fragments_set_id().unwrap();
|
||||
|
||||
|
||||
@@ -35,9 +35,9 @@ impl From<io::Error> for SphinxCodecError {
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<io::Error> for SphinxCodecError {
|
||||
fn into(self) -> io::Error {
|
||||
match self {
|
||||
impl From<SphinxCodecError> for io::Error {
|
||||
fn from(err: SphinxCodecError) -> Self {
|
||||
match err {
|
||||
SphinxCodecError::InvalidPacketSize => {
|
||||
io::Error::new(io::ErrorKind::InvalidInput, "invalid packet size")
|
||||
}
|
||||
@@ -72,7 +72,7 @@ impl Encoder<FramedSphinxPacket> for SphinxCodec {
|
||||
type Error = SphinxCodecError;
|
||||
|
||||
fn encode(&mut self, item: FramedSphinxPacket, dst: &mut BytesMut) -> Result<(), Self::Error> {
|
||||
item.header.encode(dst)?;
|
||||
item.header.encode(dst);
|
||||
dst.put(item.packet.to_bytes().as_ref());
|
||||
Ok(())
|
||||
}
|
||||
@@ -236,7 +236,7 @@ mod packet_encoding {
|
||||
packet_mode: Default::default(),
|
||||
};
|
||||
let mut bytes = BytesMut::new();
|
||||
header.encode(&mut bytes).unwrap();
|
||||
header.encode(&mut bytes);
|
||||
assert!(SphinxCodec.decode(&mut bytes).unwrap().is_none());
|
||||
|
||||
assert_eq!(bytes.capacity(), Header::SIZE + packet_size.size())
|
||||
|
||||
@@ -75,14 +75,13 @@ pub struct Header {
|
||||
impl Header {
|
||||
pub(crate) const SIZE: usize = 2;
|
||||
|
||||
pub(crate) fn encode(&self, dst: &mut BytesMut) -> Result<(), SphinxCodecError> {
|
||||
pub(crate) fn encode(&self, dst: &mut BytesMut) {
|
||||
// we reserve one byte for `packet_size` and the other for `mode`
|
||||
dst.reserve(Self::SIZE);
|
||||
dst.put_u8(self.packet_size as u8);
|
||||
dst.put_u8(self.packet_mode as u8);
|
||||
// reserve bytes for the actual packet
|
||||
dst.reserve(self.packet_size.size());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn decode(src: &mut BytesMut) -> Result<Option<Self>, SphinxCodecError> {
|
||||
@@ -107,7 +106,7 @@ mod header_encoding {
|
||||
fn header_can_be_decoded_from_a_valid_encoded_instance() {
|
||||
let header = Header::default();
|
||||
let mut bytes = BytesMut::new();
|
||||
header.encode(&mut bytes).unwrap();
|
||||
header.encode(&mut bytes);
|
||||
let decoded = Header::decode(&mut bytes).unwrap().unwrap();
|
||||
assert_eq!(decoded, header);
|
||||
}
|
||||
@@ -158,7 +157,7 @@ mod header_encoding {
|
||||
packet_mode: Default::default(),
|
||||
};
|
||||
let mut bytes = BytesMut::new();
|
||||
header.encode(&mut bytes).unwrap();
|
||||
header.encode(&mut bytes);
|
||||
assert_eq!(bytes.capacity(), bytes.len() + packet_size.size())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,7 +141,7 @@ impl VPNManager {
|
||||
.load(Ordering::SeqCst)
|
||||
}
|
||||
|
||||
pub(super) async fn use_secret<'a, R>(&'a mut self, rng: R) -> SpinhxKeyRef<'a>
|
||||
pub(super) async fn use_secret<R>(&mut self, rng: R) -> SpinhxKeyRef<'_>
|
||||
where
|
||||
R: CryptoRng + Rng,
|
||||
{
|
||||
|
||||
@@ -15,7 +15,6 @@ pub struct OrderedMessageBuffer {
|
||||
|
||||
impl OrderedMessageBuffer {
|
||||
pub fn new() -> OrderedMessageBuffer {
|
||||
trace!("Creating ordered message buffer.");
|
||||
OrderedMessageBuffer {
|
||||
next_index: 0,
|
||||
messages: HashMap::new(),
|
||||
@@ -71,6 +70,12 @@ impl OrderedMessageBuffer {
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for OrderedMessageBuffer {
|
||||
fn default() -> Self {
|
||||
OrderedMessageBuffer::new()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test_chunking_and_reassembling {
|
||||
use super::*;
|
||||
|
||||
@@ -24,6 +24,12 @@ impl OrderedMessageSender {
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for OrderedMessageSender {
|
||||
fn default() -> Self {
|
||||
OrderedMessageSender::new()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod ordered_message_sender {
|
||||
use super::*;
|
||||
|
||||
@@ -90,7 +90,7 @@ impl<'a, R: AsyncRead + Unpin> Stream for AvailableReader<'a, R> {
|
||||
// if we read a non-0 amount, we're not done yet!
|
||||
if n == 0 {
|
||||
let buf = self.buf.replace(BytesMut::new());
|
||||
if buf.len() > 0 {
|
||||
if !buf.is_empty() {
|
||||
Poll::Ready(Some(Ok(buf.freeze())))
|
||||
} else {
|
||||
Poll::Ready(None)
|
||||
|
||||
@@ -159,17 +159,18 @@ impl Controller {
|
||||
// TODO:
|
||||
// TODO:
|
||||
}
|
||||
} else if !self.recently_closed.contains(&conn_id) {
|
||||
warn!("Received a 'Send' before 'Connect' - going to buffer the data");
|
||||
let pending = self
|
||||
.pending_messages
|
||||
.entry(conn_id)
|
||||
.or_insert_with(Vec::new);
|
||||
pending.push((payload, is_closed));
|
||||
} else {
|
||||
if !self.recently_closed.contains(&conn_id) {
|
||||
warn!("Received a 'Send' before 'Connect' - going to buffer the data");
|
||||
let pending = self.pending_messages.entry(conn_id).or_insert(Vec::new());
|
||||
pending.push((payload, is_closed));
|
||||
} else {
|
||||
error!(
|
||||
"Tried to write to closed connection ({} bytes were 'lost)",
|
||||
payload.len()
|
||||
)
|
||||
}
|
||||
error!(
|
||||
"Tried to write to closed connection ({} bytes were 'lost)",
|
||||
payload.len()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,11 +29,11 @@ pub struct ProxyMessage {
|
||||
pub socket_closed: bool,
|
||||
}
|
||||
|
||||
impl Into<ProxyMessage> for (Vec<u8>, bool) {
|
||||
fn into(self) -> ProxyMessage {
|
||||
impl From<(Vec<u8>, bool)> for ProxyMessage {
|
||||
fn from(data: (Vec<u8>, bool)) -> Self {
|
||||
ProxyMessage {
|
||||
data: self.0,
|
||||
socket_closed: self.1,
|
||||
data: data.0,
|
||||
socket_closed: data.1,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,12 +43,12 @@ impl filter::Versioned for Node {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Into<SphinxNode> for &'a Node {
|
||||
fn into(self) -> SphinxNode {
|
||||
let node_address_bytes = NymNodeRoutingAddress::from(self.mixnet_listener)
|
||||
impl<'a> From<&'a Node> for SphinxNode {
|
||||
fn from(node: &'a Node) -> Self {
|
||||
let node_address_bytes = NymNodeRoutingAddress::from(node.mixnet_listener)
|
||||
.try_into()
|
||||
.unwrap();
|
||||
|
||||
SphinxNode::new(node_address_bytes, (&self.sphinx_key).into())
|
||||
SphinxNode::new(node_address_bytes, (&node.sphinx_key).into())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ impl NymTopology {
|
||||
{
|
||||
let gateway = self
|
||||
.get_gateway(gateway_identity)
|
||||
.ok_or_else(|| NymTopologyError::NonExistentGatewayError)?;
|
||||
.ok_or(NymTopologyError::NonExistentGatewayError)?;
|
||||
|
||||
Ok(self
|
||||
.random_mix_route(rng, num_mix_hops)?
|
||||
@@ -224,11 +224,7 @@ mod converting_mixes_to_vec {
|
||||
|
||||
let topology = NymTopology::new(mixes, vec![]);
|
||||
let mixvec = topology.mixes_as_vec();
|
||||
assert!(mixvec
|
||||
.iter()
|
||||
.map(|node| node.location.clone())
|
||||
.collect::<Vec<String>>()
|
||||
.contains(&"London".to_string()));
|
||||
assert!(mixvec.iter().any(|node| node.location == "London"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -37,10 +37,10 @@ impl filter::Versioned for Node {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Into<SphinxNode> for &'a Node {
|
||||
fn into(self) -> SphinxNode {
|
||||
let node_address_bytes = NymNodeRoutingAddress::from(self.host).try_into().unwrap();
|
||||
impl<'a> From<&'a Node> for SphinxNode {
|
||||
fn from(node: &'a Node) -> Self {
|
||||
let node_address_bytes = NymNodeRoutingAddress::from(node.host).try_into().unwrap();
|
||||
|
||||
SphinxNode::new(node_address_bytes, (&self.sphinx_key).into())
|
||||
SphinxNode::new(node_address_bytes, (&node.sphinx_key).into())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,8 +89,8 @@ impl EncryptedAddressBytes {
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<String> for EncryptedAddressBytes {
|
||||
fn into(self) -> String {
|
||||
self.to_base58_string()
|
||||
impl From<EncryptedAddressBytes> for String {
|
||||
fn from(val: EncryptedAddressBytes) -> Self {
|
||||
val.to_base58_string()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,8 +73,8 @@ impl AuthenticationIV {
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<String> for AuthenticationIV {
|
||||
fn into(self) -> String {
|
||||
self.to_base58_string()
|
||||
impl From<AuthenticationIV> for String {
|
||||
fn from(iv: AuthenticationIV) -> Self {
|
||||
iv.to_base58_string()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,13 +18,9 @@ use self::gateway::GatewayHandshake;
|
||||
pub use self::shared_key::{SharedKeySize, SharedKeys};
|
||||
use crypto::asymmetric::identity;
|
||||
use futures::{Sink, Stream};
|
||||
use rand::rngs::OsRng;
|
||||
use rand::{CryptoRng, RngCore};
|
||||
use tungstenite::{Error as WsError, Message as WsMessage};
|
||||
|
||||
// for ease of use
|
||||
pub const DEFAULT_RNG: OsRng = OsRng;
|
||||
|
||||
pub(crate) type WsItem = Result<WsMessage, WsError>;
|
||||
|
||||
mod client;
|
||||
|
||||
@@ -149,9 +149,9 @@ impl SharedKeys {
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<String> for SharedKeys {
|
||||
fn into(self) -> String {
|
||||
self.to_base58_string()
|
||||
impl From<SharedKeys> for String {
|
||||
fn from(keys: SharedKeys) -> Self {
|
||||
keys.to_base58_string()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ impl<'a, S> State<'a, S> {
|
||||
identity: &'a identity::KeyPair,
|
||||
remote_pubkey: Option<identity::PublicKey>,
|
||||
) -> Self {
|
||||
let ephemeral_keypair = encryption::KeyPair::new_with_rng(rng);
|
||||
let ephemeral_keypair = encryption::KeyPair::new(rng);
|
||||
State {
|
||||
ws_stream,
|
||||
ephemeral_keypair,
|
||||
|
||||
@@ -139,11 +139,11 @@ impl ClientControlRequest {
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<Message> for ClientControlRequest {
|
||||
fn into(self) -> Message {
|
||||
impl From<ClientControlRequest> for Message {
|
||||
fn from(req: ClientControlRequest) -> Self {
|
||||
// it should be safe to call `unwrap` here as the message is generated by the server
|
||||
// so if it fails (and consequently panics) it's a bug that should be resolved
|
||||
let str_req = serde_json::to_string(&self).unwrap();
|
||||
let str_req = serde_json::to_string(&req).unwrap();
|
||||
Message::Text(str_req)
|
||||
}
|
||||
}
|
||||
@@ -193,11 +193,11 @@ impl ServerResponse {
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<Message> for ServerResponse {
|
||||
fn into(self) -> Message {
|
||||
impl From<ServerResponse> for Message {
|
||||
fn from(res: ServerResponse) -> Self {
|
||||
// it should be safe to call `unwrap` here as the message is generated by the server
|
||||
// so if it fails (and consequently panics) it's a bug that should be resolved
|
||||
let str_res = serde_json::to_string(&self).unwrap();
|
||||
let str_res = serde_json::to_string(&res).unwrap();
|
||||
Message::Text(str_res)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,8 +128,10 @@ pub fn execute(matches: &ArgMatches) {
|
||||
|
||||
// if gateway was already initialised, don't generate new keys
|
||||
if !already_init {
|
||||
let identity_keys = identity::KeyPair::new();
|
||||
let sphinx_keys = encryption::KeyPair::new();
|
||||
let mut rng = rand::rngs::OsRng;
|
||||
|
||||
let identity_keys = identity::KeyPair::new(&mut rng);
|
||||
let sphinx_keys = encryption::KeyPair::new(&mut rng);
|
||||
let pathfinder = GatewayPathfinder::new_from_config(&config);
|
||||
pemstore::store_keypair(
|
||||
&sphinx_keys,
|
||||
|
||||
@@ -26,12 +26,13 @@ use futures::{
|
||||
use gateway_requests::authentication::encrypted_address::EncryptedAddressBytes;
|
||||
use gateway_requests::authentication::iv::AuthenticationIV;
|
||||
use gateway_requests::registration::handshake::error::HandshakeError;
|
||||
use gateway_requests::registration::handshake::{gateway_handshake, SharedKeys, DEFAULT_RNG};
|
||||
use gateway_requests::registration::handshake::{gateway_handshake, SharedKeys};
|
||||
use gateway_requests::types::{BinaryRequest, ClientControlRequest, ServerResponse};
|
||||
use gateway_requests::BinaryResponse;
|
||||
use log::*;
|
||||
use mixnet_client::forwarder::MixForwardingSender;
|
||||
use nymsphinx::DestinationAddressBytes;
|
||||
use rand::{CryptoRng, Rng};
|
||||
use std::convert::TryFrom;
|
||||
use std::sync::Arc;
|
||||
use tokio::{prelude::*, stream::StreamExt};
|
||||
@@ -58,7 +59,8 @@ impl<S> SocketStream<S> {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct Handle<S> {
|
||||
pub(crate) struct Handle<R, S> {
|
||||
rng: R,
|
||||
remote_address: Option<DestinationAddressBytes>,
|
||||
shared_key: Option<SharedKeys>,
|
||||
clients_handler_sender: ClientsHandlerRequestSender,
|
||||
@@ -68,16 +70,21 @@ pub(crate) struct Handle<S> {
|
||||
local_identity: Arc<identity::KeyPair>,
|
||||
}
|
||||
|
||||
impl<S> Handle<S> {
|
||||
impl<R, S> Handle<R, S>
|
||||
where
|
||||
R: Rng + CryptoRng,
|
||||
{
|
||||
// for time being we assume handle is always constructed from raw socket.
|
||||
// if we decide we want to change it, that's not too difficult
|
||||
pub(crate) fn new(
|
||||
rng: R,
|
||||
conn: S,
|
||||
clients_handler_sender: ClientsHandlerRequestSender,
|
||||
outbound_mix_sender: MixForwardingSender,
|
||||
local_identity: Arc<identity::KeyPair>,
|
||||
) -> Self {
|
||||
Handle {
|
||||
rng,
|
||||
remote_address: None,
|
||||
shared_key: None,
|
||||
clients_handler_sender,
|
||||
@@ -121,7 +128,7 @@ impl<S> Handle<S> {
|
||||
match &mut self.socket_connection {
|
||||
SocketStream::UpgradedWebSocket(ws_stream) => {
|
||||
gateway_handshake(
|
||||
&mut DEFAULT_RNG,
|
||||
&mut self.rng,
|
||||
ws_stream,
|
||||
self.local_identity.as_ref(),
|
||||
init_msg,
|
||||
|
||||
@@ -17,6 +17,7 @@ use crate::node::client_handling::websocket::connection_handler::Handle;
|
||||
use crypto::asymmetric::identity;
|
||||
use log::*;
|
||||
use mixnet_client::forwarder::MixForwardingSender;
|
||||
use rand::rngs::OsRng;
|
||||
use std::net::SocketAddr;
|
||||
use std::sync::Arc;
|
||||
use tokio::task::JoinHandle;
|
||||
@@ -51,6 +52,7 @@ impl Listener {
|
||||
// TODO: I think we *REALLY* need a mechanism for having a maximum number of connected
|
||||
// clients or spawned tokio tasks -> perhaps a worker system?
|
||||
let mut handle = Handle::new(
|
||||
OsRng,
|
||||
socket,
|
||||
clients_handler_sender.clone(),
|
||||
outbound_mix_sender.clone(),
|
||||
|
||||
@@ -189,14 +189,9 @@ impl Gateway {
|
||||
}
|
||||
|
||||
if let Err(err) = presence::register_with_validator(
|
||||
self.config.get_validator_rest_endpoint(),
|
||||
self.config.get_mix_announce_address(),
|
||||
self.config.get_clients_announce_address(),
|
||||
&self.config,
|
||||
self.identity.public_key().to_base58_string(),
|
||||
self.encryption_keys.public_key().to_base58_string(),
|
||||
self.config.get_version().to_string(),
|
||||
self.config.get_location(),
|
||||
self.config.get_incentives_address()
|
||||
).await {
|
||||
error!("failed to register with the validator - {:?}", err);
|
||||
return
|
||||
|
||||
@@ -12,32 +12,28 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use crate::config::Config;
|
||||
use validator_client::models::gateway::GatewayRegistrationInfo;
|
||||
use validator_client::ValidatorClientError;
|
||||
|
||||
// there's no point in keeping the validator client persistently as it might be literally hours or days
|
||||
// before it's used again
|
||||
pub(crate) async fn register_with_validator(
|
||||
validator_endpoint: String,
|
||||
mix_host: String,
|
||||
clients_host: String,
|
||||
gateway_config: &Config,
|
||||
identity_key: String,
|
||||
sphinx_key: String,
|
||||
version: String,
|
||||
location: String,
|
||||
incentives_address: Option<String>,
|
||||
) -> Result<(), ValidatorClientError> {
|
||||
let config = validator_client::Config::new(validator_endpoint);
|
||||
let config = validator_client::Config::new(gateway_config.get_validator_rest_endpoint());
|
||||
let validator_client = validator_client::Client::new(config);
|
||||
|
||||
let registration_info = GatewayRegistrationInfo::new(
|
||||
mix_host,
|
||||
clients_host,
|
||||
gateway_config.get_mix_announce_address(),
|
||||
gateway_config.get_clients_announce_address(),
|
||||
identity_key,
|
||||
sphinx_key,
|
||||
version,
|
||||
location,
|
||||
incentives_address,
|
||||
gateway_config.get_version().to_string(),
|
||||
gateway_config.get_location(),
|
||||
gateway_config.get_incentives_address(),
|
||||
);
|
||||
|
||||
validator_client.register_gateway(registration_info).await
|
||||
|
||||
@@ -22,9 +22,9 @@ use std::path::PathBuf;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) enum ClientLedgerError {
|
||||
DbReadError(sled::Error),
|
||||
DbWriteError(sled::Error),
|
||||
DbOpenError(sled::Error),
|
||||
Read(sled::Error),
|
||||
Write(sled::Error),
|
||||
Open(sled::Error),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@@ -37,7 +37,7 @@ pub(crate) struct ClientLedger {
|
||||
impl ClientLedger {
|
||||
pub(crate) fn load(file: PathBuf) -> Result<Self, ClientLedgerError> {
|
||||
let db = match sled::open(file) {
|
||||
Err(e) => return Err(ClientLedgerError::DbOpenError(e)),
|
||||
Err(e) => return Err(ClientLedgerError::Open(e)),
|
||||
Ok(db) => db,
|
||||
};
|
||||
|
||||
@@ -93,7 +93,7 @@ impl ClientLedger {
|
||||
iv: &AuthenticationIV,
|
||||
) -> Result<bool, ClientLedgerError> {
|
||||
match self.db.get(&client_address.to_bytes()) {
|
||||
Err(e) => Err(ClientLedgerError::DbReadError(e)),
|
||||
Err(e) => Err(ClientLedgerError::Read(e)),
|
||||
Ok(existing_key) => match existing_key {
|
||||
Some(existing_key_ivec) => {
|
||||
let shared_key = &self.read_shared_key(existing_key_ivec);
|
||||
@@ -109,7 +109,7 @@ impl ClientLedger {
|
||||
client_address: &DestinationAddressBytes,
|
||||
) -> Result<Option<SharedKeys>, ClientLedgerError> {
|
||||
match self.db.get(&client_address.to_bytes()) {
|
||||
Err(e) => Err(ClientLedgerError::DbReadError(e)),
|
||||
Err(e) => Err(ClientLedgerError::Read(e)),
|
||||
Ok(existing_key) => Ok(existing_key.map(|key_ivec| self.read_shared_key(key_ivec))),
|
||||
}
|
||||
}
|
||||
@@ -123,7 +123,7 @@ impl ClientLedger {
|
||||
.db
|
||||
.insert(&client_address.to_bytes(), shared_key.to_bytes())
|
||||
{
|
||||
Err(e) => Err(ClientLedgerError::DbWriteError(e)),
|
||||
Err(e) => Err(ClientLedgerError::Write(e)),
|
||||
Ok(existing_key) => {
|
||||
Ok(existing_key.map(|existing_key| self.read_shared_key(existing_key)))
|
||||
}
|
||||
@@ -139,7 +139,7 @@ impl ClientLedger {
|
||||
client_address: &DestinationAddressBytes,
|
||||
) -> Result<Option<SharedKeys>, ClientLedgerError> {
|
||||
let removal_result = match self.db.remove(&client_address.to_bytes()) {
|
||||
Err(e) => Err(ClientLedgerError::DbWriteError(e)),
|
||||
Err(e) => Err(ClientLedgerError::Write(e)),
|
||||
Ok(existing_key) => {
|
||||
Ok(existing_key.map(|existing_key| self.read_shared_key(existing_key)))
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ futures = "0.3.1"
|
||||
humantime-serde = "1.0.1"
|
||||
log = "0.4"
|
||||
pretty_env_logger = "0.3"
|
||||
rand = "0.7"
|
||||
serde = { version = "1.0.104", features = ["derive"] }
|
||||
tokio = { version = "0.2", features = ["full"] }
|
||||
tokio-util = { version = "0.3.1", features = ["codec"] }
|
||||
|
||||
@@ -154,8 +154,10 @@ pub fn execute(matches: &ArgMatches) {
|
||||
|
||||
// if node was already initialised, don't generate new keys
|
||||
if !already_init {
|
||||
let identity_keys = identity::KeyPair::new();
|
||||
let sphinx_keys = encryption::KeyPair::new();
|
||||
let mut rng = rand::rngs::OsRng;
|
||||
|
||||
let identity_keys = identity::KeyPair::new(&mut rng);
|
||||
let sphinx_keys = encryption::KeyPair::new(&mut rng);
|
||||
let pathfinder = MixNodePathfinder::new_from_config(&config);
|
||||
pemstore::store_keypair(
|
||||
&identity_keys,
|
||||
|
||||
@@ -124,7 +124,9 @@ fn pre_090_upgrade(from: &str, config: Config, matches: &ArgMatches) -> Config {
|
||||
);
|
||||
|
||||
println!("Generating new identity...");
|
||||
let identity_keys = identity::KeyPair::new();
|
||||
let mut rng = rand::rngs::OsRng;
|
||||
|
||||
let identity_keys = identity::KeyPair::new(&mut rng);
|
||||
upgraded_config.set_default_identity_keypair_paths();
|
||||
|
||||
if let Err(err) = pemstore::store_keypair(
|
||||
|
||||
@@ -154,14 +154,9 @@ impl MixNode {
|
||||
}
|
||||
|
||||
if let Err(err) = presence::register_with_validator(
|
||||
self.config.get_validator_rest_endpoint(),
|
||||
self.config.get_announce_address(),
|
||||
&self.config,
|
||||
self.identity_keypair.public_key().to_base58_string(),
|
||||
self.sphinx_keypair.public_key().to_base58_string(),
|
||||
self.config.get_version().to_string(),
|
||||
self.config.get_location(),
|
||||
self.config.get_layer(),
|
||||
self.config.get_incentives_address(),
|
||||
).await {
|
||||
error!("failed to register with the validator - {:?}", err);
|
||||
return;
|
||||
|
||||
@@ -12,32 +12,28 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use crate::config::Config;
|
||||
use validator_client::models::mixnode::MixRegistrationInfo;
|
||||
use validator_client::ValidatorClientError;
|
||||
|
||||
// there's no point in keeping the validator client persistently as it might be literally hours or days
|
||||
// before it's used again
|
||||
pub(crate) async fn register_with_validator(
|
||||
validator_endpoint: String,
|
||||
mix_host: String,
|
||||
mixnode_config: &Config,
|
||||
identity_key: String,
|
||||
sphinx_key: String,
|
||||
version: String,
|
||||
location: String,
|
||||
layer: u64,
|
||||
incentives_address: Option<String>,
|
||||
) -> Result<(), ValidatorClientError> {
|
||||
let config = validator_client::Config::new(validator_endpoint);
|
||||
let config = validator_client::Config::new(mixnode_config.get_validator_rest_endpoint());
|
||||
let validator_client = validator_client::Client::new(config);
|
||||
|
||||
let registration_info = MixRegistrationInfo::new(
|
||||
mix_host,
|
||||
mixnode_config.get_announce_address(),
|
||||
identity_key,
|
||||
sphinx_key,
|
||||
version,
|
||||
location,
|
||||
layer,
|
||||
incentives_address,
|
||||
mixnode_config.get_version().to_string(),
|
||||
mixnode_config.get_location(),
|
||||
mixnode_config.get_layer(),
|
||||
mixnode_config.get_incentives_address(),
|
||||
);
|
||||
|
||||
validator_client.register_mix(registration_info).await
|
||||
|
||||
@@ -12,12 +12,12 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use crate::{DefRng, DEFAULT_RNG};
|
||||
use nymsphinx::forwarding::packet::MixPacket;
|
||||
use nymsphinx::params::PacketMode;
|
||||
use nymsphinx::{
|
||||
acknowledgements::AckKey, addressing::clients::Recipient, preparer::MessagePreparer,
|
||||
};
|
||||
use rand::rngs::OsRng;
|
||||
use std::time::Duration;
|
||||
use topology::NymTopology;
|
||||
|
||||
@@ -25,18 +25,18 @@ const DEFAULT_AVERAGE_PACKET_DELAY: Duration = Duration::from_millis(200);
|
||||
const DEFAULT_AVERAGE_ACK_DELAY: Duration = Duration::from_millis(200);
|
||||
|
||||
pub(crate) struct Chunker {
|
||||
rng: DefRng,
|
||||
rng: OsRng,
|
||||
me: Recipient,
|
||||
message_preparer: MessagePreparer<DefRng>,
|
||||
message_preparer: MessagePreparer<OsRng>,
|
||||
}
|
||||
|
||||
impl Chunker {
|
||||
pub(crate) fn new(me: Recipient) -> Self {
|
||||
Chunker {
|
||||
rng: DEFAULT_RNG,
|
||||
rng: OsRng,
|
||||
me,
|
||||
message_preparer: MessagePreparer::new(
|
||||
DEFAULT_RNG,
|
||||
OsRng,
|
||||
me,
|
||||
DEFAULT_AVERAGE_PACKET_DELAY,
|
||||
DEFAULT_AVERAGE_ACK_DELAY,
|
||||
|
||||
@@ -25,7 +25,6 @@ use monitor::{AckSender, MixnetSender, Monitor};
|
||||
use notifications::Notifier;
|
||||
use nymsphinx::addressing::clients::Recipient;
|
||||
use packet_sender::PacketSender;
|
||||
use rand::rngs::OsRng;
|
||||
use std::sync::Arc;
|
||||
use std::time;
|
||||
use std::time::Duration;
|
||||
@@ -39,9 +38,6 @@ mod run_info;
|
||||
mod test_packet;
|
||||
mod tested_network;
|
||||
|
||||
pub(crate) type DefRng = OsRng;
|
||||
pub(crate) const DEFAULT_RNG: DefRng = OsRng;
|
||||
|
||||
const V4_TOPOLOGY_ARG: &str = "v4-topology-filepath";
|
||||
const V6_TOPOLOGY_ARG: &str = "v6-topology-filepath";
|
||||
const VALIDATOR_ARG: &str = "validator";
|
||||
@@ -103,9 +99,7 @@ async fn main() {
|
||||
let v4_topology = parse_topology_file(v4_topology_path);
|
||||
let v6_topology = parse_topology_file(v6_topology_path);
|
||||
|
||||
let validator_rest_uri = matches
|
||||
.value_of(VALIDATOR_ARG)
|
||||
.unwrap_or_else(|| DEFAULT_VALIDATOR);
|
||||
let validator_rest_uri = matches.value_of(VALIDATOR_ARG).unwrap_or(DEFAULT_VALIDATOR);
|
||||
let detailed_report = matches.is_present(DETAILED_REPORT_ARG);
|
||||
let sending_rate = matches
|
||||
.value_of(GATEWAY_SENDING_RATE_ARG)
|
||||
@@ -133,8 +127,10 @@ async fn main() {
|
||||
|
||||
// Generate a new set of identity keys. These are ephemeral, and change on each run.
|
||||
// JS: do they? or rather should they?
|
||||
let identity_keypair = identity::KeyPair::new();
|
||||
let encryption_keypair = encryption::KeyPair::new();
|
||||
let mut rng = rand::rngs::OsRng;
|
||||
|
||||
let identity_keypair = identity::KeyPair::new(&mut rng);
|
||||
let encryption_keypair = encryption::KeyPair::new(&mut rng);
|
||||
|
||||
// We need our own address as a Recipient so we can send ourselves test packets
|
||||
let self_address = Recipient::new(
|
||||
|
||||
@@ -136,7 +136,7 @@ impl Notifier {
|
||||
.message_receiver
|
||||
.insert_new_fragment(fragment)
|
||||
.map_err(|_| NotifierError::MalformedPacketReceived)?
|
||||
.ok_or_else(|| NotifierError::NonTestPacketReceived)?; // if it's a test packet it MUST BE reconstructed with single fragment
|
||||
.ok_or(NotifierError::NonTestPacketReceived)?; // if it's a test packet it MUST BE reconstructed with single fragment
|
||||
|
||||
let all_received = self.current_test_run.received_packet(recovered.message);
|
||||
if all_received {
|
||||
|
||||
@@ -77,11 +77,7 @@ impl PacketSender {
|
||||
if version.major == 0 && version.minor >= 10 {
|
||||
return true;
|
||||
}
|
||||
if version.minor >= 9 && version.patch >= 2 {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
version.minor >= 9 && version.patch >= 2
|
||||
} else {
|
||||
false
|
||||
}
|
||||
@@ -96,7 +92,7 @@ impl PacketSender {
|
||||
match mix {
|
||||
Err(err) => {
|
||||
error!("mix {} is malformed - {:?}", mix_id, err);
|
||||
TestMix::MalformedMix(mix_id)
|
||||
TestMix::Malformed(mix_id)
|
||||
}
|
||||
Ok(mix) => {
|
||||
if self.check_version_compatibility(&mix.version) {
|
||||
@@ -105,9 +101,9 @@ impl PacketSender {
|
||||
let v6_test_packet =
|
||||
TestPacket::new(mix.identity_key, IpVersion::V6, self.nonce);
|
||||
|
||||
TestMix::ValidMix(mix, [v4_test_packet, v6_test_packet])
|
||||
TestMix::Valid(mix, [v4_test_packet, v6_test_packet])
|
||||
} else {
|
||||
TestMix::IncompatibleMix(mix)
|
||||
TestMix::Incompatible(mix)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -133,12 +129,12 @@ impl PacketSender {
|
||||
|
||||
for test_mix in test_mixes {
|
||||
match test_mix {
|
||||
TestMix::ValidMix(.., mix_test_packets) => {
|
||||
TestMix::Valid(.., mix_test_packets) => {
|
||||
test_packets.push(mix_test_packets[0]);
|
||||
test_packets.push(mix_test_packets[1]);
|
||||
}
|
||||
TestMix::MalformedMix(pub_key) => malformed_mixes.push(pub_key.clone()),
|
||||
TestMix::IncompatibleMix(mix) => incompatible_mixes
|
||||
TestMix::Malformed(pub_key) => malformed_mixes.push(pub_key.clone()),
|
||||
TestMix::Incompatible(mix) => incompatible_mixes
|
||||
.push((mix.identity_key.to_base58_string(), mix.version.clone())),
|
||||
}
|
||||
}
|
||||
@@ -177,7 +173,7 @@ impl PacketSender {
|
||||
|
||||
for test_mix in test_mixes {
|
||||
match test_mix {
|
||||
TestMix::ValidMix(mixnode, test_packets) => {
|
||||
TestMix::Valid(mixnode, test_packets) => {
|
||||
let mut node_mix_packets =
|
||||
self.prepare_node_mix_packets(mixnode, test_packets).await;
|
||||
mix_packets.append(&mut node_mix_packets);
|
||||
|
||||
@@ -57,9 +57,9 @@ impl IpVersion {
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<String> for IpVersion {
|
||||
fn into(self) -> String {
|
||||
format!("{}", self)
|
||||
impl From<IpVersion> for String {
|
||||
fn from(ipv: IpVersion) -> Self {
|
||||
format!("{}", ipv)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,14 +24,14 @@ use topology::{mix, NymTopology};
|
||||
pub(crate) mod good_topology;
|
||||
|
||||
pub(crate) enum TestMix {
|
||||
ValidMix(mix::Node, [TestPacket; 2]),
|
||||
IncompatibleMix(mix::Node),
|
||||
MalformedMix(String),
|
||||
Valid(mix::Node, [TestPacket; 2]),
|
||||
Incompatible(mix::Node),
|
||||
Malformed(String),
|
||||
}
|
||||
|
||||
impl TestMix {
|
||||
pub(crate) fn is_valid(&self) -> bool {
|
||||
matches!(self, TestMix::ValidMix(..))
|
||||
matches!(self, TestMix::Valid(..))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -112,7 +112,7 @@ impl HostsStore {
|
||||
HostsStore { storefile, hosts }
|
||||
}
|
||||
|
||||
fn append(path: &PathBuf, text: &str) {
|
||||
fn append(path: &Path, text: &str) {
|
||||
use std::io::Write;
|
||||
let mut file = OpenOptions::new()
|
||||
.write(true)
|
||||
|
||||
Reference in New Issue
Block a user