mix throughput tester (#5661)
* wip: sending with single client * tag packets to measure latency * constantly logging rates * concurrency * adjusting some values * write results to files upon completion
This commit is contained in:
committed by
GitHub
parent
89eea3100e
commit
d062524d32
@@ -1,7 +1,6 @@
|
||||
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use crate::node::mixnet::packet_forwarding::global::is_global_ip;
|
||||
use crate::node::shared_network::RoutingFilter;
|
||||
use futures::StreamExt;
|
||||
use nym_mixnet_client::forwarder::{
|
||||
@@ -13,38 +12,33 @@ use nym_nonexhaustive_delayqueue::{Expired, NonExhaustiveDelayQueue};
|
||||
use nym_sphinx_forwarding::packet::MixPacket;
|
||||
use nym_task::ShutdownToken;
|
||||
use std::io;
|
||||
use std::net::IpAddr;
|
||||
use tokio::time::Instant;
|
||||
use tracing::{debug, error, trace, warn};
|
||||
|
||||
pub(crate) mod global;
|
||||
|
||||
pub struct PacketForwarder<C> {
|
||||
testnet: bool,
|
||||
|
||||
pub struct PacketForwarder<C, F> {
|
||||
delay_queue: NonExhaustiveDelayQueue<MixPacket>,
|
||||
mixnet_client: C,
|
||||
|
||||
metrics: NymNodeMetrics,
|
||||
routing_filter: RoutingFilter,
|
||||
routing_filter: F,
|
||||
|
||||
packet_sender: MixForwardingSender,
|
||||
packet_receiver: MixForwardingReceiver,
|
||||
shutdown: ShutdownToken,
|
||||
}
|
||||
|
||||
impl<C> PacketForwarder<C> {
|
||||
impl<C, F> PacketForwarder<C, F> {
|
||||
pub fn new(
|
||||
client: C,
|
||||
testnet: bool,
|
||||
routing_filter: RoutingFilter,
|
||||
routing_filter: F,
|
||||
metrics: NymNodeMetrics,
|
||||
shutdown: ShutdownToken,
|
||||
) -> Self {
|
||||
let (packet_sender, packet_receiver) = mix_forwarding_channels();
|
||||
|
||||
PacketForwarder {
|
||||
testnet,
|
||||
delay_queue: NonExhaustiveDelayQueue::new(),
|
||||
mixnet_client: client,
|
||||
metrics,
|
||||
@@ -59,22 +53,14 @@ impl<C> PacketForwarder<C> {
|
||||
self.packet_sender.clone()
|
||||
}
|
||||
|
||||
fn should_route(&mut self, ip_addr: IpAddr) -> bool {
|
||||
// only allow non-global ips on testnets
|
||||
if self.testnet && !is_global_ip(&ip_addr) {
|
||||
return true;
|
||||
}
|
||||
|
||||
self.routing_filter.attempt_resolve(ip_addr).should_route()
|
||||
}
|
||||
|
||||
fn forward_packet(&mut self, packet: MixPacket)
|
||||
where
|
||||
C: SendWithoutResponse,
|
||||
F: RoutingFilter,
|
||||
{
|
||||
let next_hop = packet.next_hop();
|
||||
|
||||
if !self.should_route(next_hop.as_ref().ip()) {
|
||||
if !self.routing_filter.should_route(next_hop.as_ref().ip()) {
|
||||
debug!("dropping packet as the egress address does not belong to any known node");
|
||||
self.metrics
|
||||
.mixnet
|
||||
@@ -113,6 +99,7 @@ impl<C> PacketForwarder<C> {
|
||||
fn handle_done_delaying(&mut self, packet: Expired<MixPacket>)
|
||||
where
|
||||
C: SendWithoutResponse,
|
||||
F: RoutingFilter,
|
||||
{
|
||||
let delayed_packet = packet.into_inner();
|
||||
self.forward_packet(delayed_packet);
|
||||
@@ -121,6 +108,7 @@ impl<C> PacketForwarder<C> {
|
||||
fn handle_new_packet(&mut self, new_packet: PacketToForward)
|
||||
where
|
||||
C: SendWithoutResponse,
|
||||
F: RoutingFilter,
|
||||
{
|
||||
// in case of a zero delay packet, don't bother putting it in the delay queue,
|
||||
// just forward it immediately
|
||||
@@ -152,6 +140,7 @@ impl<C> PacketForwarder<C> {
|
||||
pub async fn run(&mut self)
|
||||
where
|
||||
C: SendWithoutResponse,
|
||||
F: RoutingFilter,
|
||||
{
|
||||
let mut processed = 0;
|
||||
trace!("starting PacketForwarder");
|
||||
|
||||
@@ -29,7 +29,7 @@ use crate::node::mixnet::packet_forwarding::PacketForwarder;
|
||||
use crate::node::mixnet::shared::ProcessingConfig;
|
||||
use crate::node::mixnet::SharedFinalHopData;
|
||||
use crate::node::shared_network::{
|
||||
CachedNetwork, CachedTopologyProvider, NetworkRefresher, RoutingFilter,
|
||||
CachedNetwork, CachedTopologyProvider, NetworkRefresher, OpenFilter, RoutingFilter,
|
||||
};
|
||||
use nym_bin_common::bin_info;
|
||||
use nym_crypto::asymmetric::{ed25519, x25519};
|
||||
@@ -461,6 +461,10 @@ impl NymNode {
|
||||
&self.config
|
||||
}
|
||||
|
||||
pub(crate) fn shutdown_token<S: Into<String>>(&self, child_suffix: S) -> ShutdownToken {
|
||||
self.shutdown_manager.clone_token(child_suffix)
|
||||
}
|
||||
|
||||
pub(crate) fn with_accepted_operator_terms_and_conditions(
|
||||
mut self,
|
||||
accepted_operator_terms_and_conditions: bool,
|
||||
@@ -528,12 +532,17 @@ impl NymNode {
|
||||
self.x25519_sphinx_keys.public_key()
|
||||
}
|
||||
|
||||
pub(crate) fn x25519_sphinx_keys(&self) -> Arc<x25519::KeyPair> {
|
||||
self.x25519_sphinx_keys.clone()
|
||||
}
|
||||
|
||||
pub(crate) fn x25519_noise_key(&self) -> &x25519::PublicKey {
|
||||
self.x25519_noise_keys.public_key()
|
||||
}
|
||||
|
||||
async fn build_network_refresher(&self) -> Result<NetworkRefresher, NymNodeError> {
|
||||
NetworkRefresher::initialise_new(
|
||||
self.config.debug.testnet,
|
||||
self.user_agent(),
|
||||
self.config.mixnet.nym_api_urls.clone(),
|
||||
self.config.debug.topology_cache_ttl,
|
||||
@@ -970,12 +979,15 @@ impl NymNode {
|
||||
events_sender
|
||||
}
|
||||
|
||||
pub(crate) fn start_mixnet_listener(
|
||||
pub(crate) fn start_mixnet_listener<F>(
|
||||
&self,
|
||||
active_clients_store: &ActiveClientsStore,
|
||||
routing_filter: RoutingFilter,
|
||||
routing_filter: F,
|
||||
shutdown: ShutdownToken,
|
||||
) -> (MixForwardingSender, ActiveConnections) {
|
||||
) -> (MixForwardingSender, ActiveConnections)
|
||||
where
|
||||
F: RoutingFilter + Send + Sync + 'static,
|
||||
{
|
||||
let processing_config = ProcessingConfig::new(&self.config);
|
||||
|
||||
// we're ALWAYS listening for mixnet packets, either for forward or final hops (or both)
|
||||
@@ -1002,7 +1014,6 @@ impl NymNode {
|
||||
|
||||
let mut packet_forwarder = PacketForwarder::new(
|
||||
mixnet_client,
|
||||
self.config.debug.testnet,
|
||||
routing_filter,
|
||||
self.metrics.clone(),
|
||||
shutdown.clone_with_suffix("mix-packet-forwarder"),
|
||||
@@ -1028,6 +1039,19 @@ impl NymNode {
|
||||
(mix_packet_sender, active_connections)
|
||||
}
|
||||
|
||||
pub(crate) async fn run_minimal_mixnet_processing(self) -> Result<(), NymNodeError> {
|
||||
self.start_mixnet_listener(
|
||||
&ActiveClientsStore::new(),
|
||||
OpenFilter,
|
||||
self.shutdown_manager.clone_token("mixnet-traffic"),
|
||||
);
|
||||
|
||||
self.shutdown_manager.close();
|
||||
self.shutdown_manager.wait_for_shutdown_signal().await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) async fn run(mut self) -> Result<(), NymNodeError> {
|
||||
info!("starting Nym Node {} with the following modes: mixnode: {}, entry: {}, exit: {}, wireguard: {}",
|
||||
self.ed25519_identity_key(),
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use crate::error::NymNodeError;
|
||||
use crate::node::mixnet::packet_forwarding::global::is_global_ip;
|
||||
use arc_swap::ArcSwap;
|
||||
use async_trait::async_trait;
|
||||
use nym_gateway::node::UserAgent;
|
||||
@@ -22,8 +23,34 @@ use tracing::log::error;
|
||||
use tracing::{debug, trace, warn};
|
||||
use url::Url;
|
||||
|
||||
pub(crate) trait RoutingFilter {
|
||||
fn should_route(&self, ip: IpAddr) -> bool;
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Default)]
|
||||
pub(crate) struct OpenFilter;
|
||||
|
||||
impl RoutingFilter for OpenFilter {
|
||||
fn should_route(&self, _: IpAddr) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl RoutingFilter for NetworkRoutingFilter {
|
||||
fn should_route(&self, ip: IpAddr) -> bool {
|
||||
// only allow non-global ips on testnets
|
||||
if self.testnet_mode && !is_global_ip(&ip) {
|
||||
return true;
|
||||
}
|
||||
|
||||
self.attempt_resolve(ip).should_route()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct RoutingFilter {
|
||||
pub(crate) struct NetworkRoutingFilter {
|
||||
testnet_mode: bool,
|
||||
|
||||
resolved: KnownNodes,
|
||||
|
||||
// while this is technically behind a lock, it should not be called too often as once resolved it will
|
||||
@@ -31,9 +58,10 @@ pub(crate) struct RoutingFilter {
|
||||
pending: UnknownNodes,
|
||||
}
|
||||
|
||||
impl RoutingFilter {
|
||||
fn new_empty() -> Self {
|
||||
RoutingFilter {
|
||||
impl NetworkRoutingFilter {
|
||||
fn new_empty(testnet_mode: bool) -> Self {
|
||||
NetworkRoutingFilter {
|
||||
testnet_mode,
|
||||
resolved: Default::default(),
|
||||
pending: Default::default(),
|
||||
}
|
||||
@@ -254,11 +282,12 @@ pub struct NetworkRefresher {
|
||||
shutdown_token: ShutdownToken,
|
||||
|
||||
network: CachedNetwork,
|
||||
routing_filter: RoutingFilter,
|
||||
routing_filter: NetworkRoutingFilter,
|
||||
}
|
||||
|
||||
impl NetworkRefresher {
|
||||
pub(crate) async fn initialise_new(
|
||||
testnet: bool,
|
||||
user_agent: UserAgent,
|
||||
nym_api_urls: Vec<Url>,
|
||||
full_refresh_interval: Duration,
|
||||
@@ -280,7 +309,7 @@ impl NetworkRefresher {
|
||||
pending_check_interval,
|
||||
shutdown_token,
|
||||
network: CachedNetwork::new_empty(),
|
||||
routing_filter: RoutingFilter::new_empty(),
|
||||
routing_filter: NetworkRoutingFilter::new_empty(testnet),
|
||||
};
|
||||
|
||||
this.obtain_initial_network().await?;
|
||||
@@ -403,7 +432,7 @@ impl NetworkRefresher {
|
||||
.map_err(|source| NymNodeError::InitialTopologyQueryFailure { source })
|
||||
}
|
||||
|
||||
pub(crate) fn routing_filter(&self) -> RoutingFilter {
|
||||
pub(crate) fn routing_filter(&self) -> NetworkRoutingFilter {
|
||||
self.routing_filter.clone()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user