mixnet 0.7.0

A mix network based on Loopix
Documentation
// Copyright 2022 Parity Technologies (UK) Ltd.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

//! Mixnet configuration.

use super::{
	packet_queues::AuthoredPacketQueueConfig,
	sphinx::{KxSecret, MAX_HOPS},
};
use std::time::Duration;

/// Configuration that can vary between sessions depending on whether the local node is a mixnode
/// or not.
#[derive(Clone, Debug)]
pub struct SessionConfig {
	/// Authored packet queue configuration.
	pub authored_packet_queue: AuthoredPacketQueueConfig,
	/// Mean period between authored packet dispatches for the session. Cover packets are sent when
	/// there are no real packets to send, or when we randomly choose to send loop cover packets
	/// (see `Config::loop_cover_proportion`). This parameter, in combination with
	/// `Config::loop_cover_proportion`, bounds the rate at which messages can be sent. Note that
	/// this period is automatically increased during session transitions to keep the overall rate
	/// stable.
	pub mean_authored_packet_period: Duration,
}

/// Mixnet configuration.
#[derive(Clone, Debug)]
pub struct Config {
	/// The target for log messages.
	pub log_target: &'static str,

	/// The number of mixnodes to connect to when we are not a mixnode ourselves. When we are a
	/// mixnode, we connect to all other mixnodes.
	pub num_gateway_mixnodes: u32,

	/// The key-exchange secret key to use in session 0. This option is intended for testing
	/// purposes only.
	pub session_0_kx_secret: Option<KxSecret>,
	/// Used by sessions in which the local node is a mixnode. If this is not the same for all
	/// nodes, delay estimates may be off.
	pub mixnode_session: SessionConfig,
	/// Used by sessions in which the local node is not a mixnode. If [`None`], we will only
	/// participate in the mixnet during sessions in which we are a mixnode.
	pub non_mixnode_session: Option<SessionConfig>,

	/// Maximum number of packets waiting for their forwarding delay to elapse. When at the limit,
	/// any packets arriving that need forwarding will simply be dropped.
	pub forward_packet_queue_capacity: usize,
	/// Mean forwarding delay at each mixnode. This should really be the same for all nodes!
	pub mean_forwarding_delay: Duration,
	/// Conservative estimate of the network (and processing) delay per hop.
	pub per_hop_net_delay: Duration,

	/// Proportion of authored packets which should be loop cover packets (as opposed to drop cover
	/// packets or real packets). If this is not the same for all nodes, delay estimates may be
	/// off.
	pub loop_cover_proportion: f64,
	/// Generate cover packets? This option is intended for testing purposes only. It essentially
	/// just drops all cover packets instead of sending them.
	pub gen_cover_packets: bool,
	/// Number of hops for packets to traverse. Some packets may traverse more hops if necessary.
	/// Note this only affects packets whose headers are generated by this node. Must be <=
	/// [`MAX_HOPS`].
	pub num_hops: usize,

	/// Maximum number of outstanding SURBs to keep keys for. Must be greater than 0.
	pub surb_keystore_capacity: usize,
	/// Maximum number of incomplete messages to keep.
	pub max_incomplete_messages: usize,
	/// Maximum number of fragments to keep across all incomplete messages.
	pub max_incomplete_fragments: usize,
	/// Maximum number of fragments per message. This should really be the same for all nodes!
	pub max_fragments_per_message: usize,
}

impl Default for Config {
	fn default() -> Self {
		Self {
			log_target: "mixnet",

			num_gateway_mixnodes: 3,

			session_0_kx_secret: None,
			mixnode_session: SessionConfig {
				authored_packet_queue: AuthoredPacketQueueConfig {
					capacity: 50,
					multiple_messages: true,
				},
				mean_authored_packet_period: Duration::from_millis(100),
			},
			non_mixnode_session: Some(SessionConfig {
				authored_packet_queue: AuthoredPacketQueueConfig {
					capacity: 25,
					// By default only allow a single message to be queued in non-mixnode sessions.
					// Replies won't be sent in non-mixnode sessions, and requests really need to
					// be buffered externally anyway to handle eg retransmission. Limiting the
					// queue to a single message means we don't need to choose a session for
					// messages until the last moment (improving behaviour around session changes),
					// and minimises SPACE_IN_AUTHORED_PACKET_QUEUE events.
					multiple_messages: false,
				},
				mean_authored_packet_period: Duration::from_millis(1000),
			}),

			forward_packet_queue_capacity: 300,
			mean_forwarding_delay: Duration::from_secs(1),
			per_hop_net_delay: Duration::from_millis(300),

			loop_cover_proportion: 0.25,
			gen_cover_packets: true,
			num_hops: MAX_HOPS,

			surb_keystore_capacity: 200,
			max_incomplete_messages: 2000,
			max_incomplete_fragments: 2000,
			max_fragments_per_message: 25,
		}
	}
}