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:
Jędrzej Stuczyński
2021-01-18 11:50:29 +00:00
committed by GitHub
parent 131574cd3c
commit 2d3b4f4b91
73 changed files with 392 additions and 315 deletions
+44
View File
@@ -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
+14
View File
@@ -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
View File
@@ -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
View File
@@ -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",
]
+3 -1
View File
@@ -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.
[![Build Status](https://travis-ci.com/nymtech/nym.svg?branch=develop)](https://travis-ci.com/nymtech/nym)
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg?style=for-the-badge)](https://opensource.org/licenses/Apache-2.0)
[![Build Status](https://img.shields.io/github/workflow/status/nymtech/nym/Continuous%20integration/develop?style=for-the-badge&logo=github-actions)](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)),
}
@@ -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,
+1 -1
View File
@@ -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()
}
}
+2 -7
View File
@@ -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();
}
+5 -6
View File
@@ -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()))?;
@@ -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);
}
+17 -21
View File
@@ -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;
+2 -7
View File
@@ -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 {
+1 -1
View File
@@ -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;
+3
View File
@@ -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"
+10 -6
View File
@@ -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(),
+3 -3
View File
@@ -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
}
}
+9 -15
View File
@@ -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;
+13 -13
View File
@@ -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)
}
}
}
}
}
+45 -30
View File
@@ -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());
+1 -1
View File
@@ -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();
+5 -5
View File
@@ -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())
+3 -4
View File
@@ -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())
}
}
+1 -1
View File
@@ -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,
{
+6 -1
View File
@@ -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,
}
}
}
+4 -4
View File
@@ -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())
}
}
+2 -6
View File
@@ -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"));
}
}
+4 -4
View File
@@ -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,
+6 -6
View File
@@ -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)
}
}
+4 -2
View File
@@ -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(),
+1 -6
View File
@@ -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
+8 -12
View File
@@ -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
+8 -8
View File
@@ -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)))
}
+1
View File
@@ -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"] }
+4 -2
View File
@@ -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,
+3 -1
View File
@@ -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(
+1 -6
View File
@@ -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;
+8 -12
View File
@@ -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
+5 -5
View File
@@ -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,
+5 -9
View File
@@ -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(
+1 -1
View File
@@ -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 {
+8 -12
View File
@@ -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);
+3 -3
View File
@@ -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)
}
}
+4 -4
View File
@@ -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)