prepare multi threaded node

This commit is contained in:
Simon Wicky
2026-05-19 11:31:14 +02:00
parent f73f1a5219
commit df566933ba
6 changed files with 69 additions and 95 deletions
+8 -10
View File
@@ -15,14 +15,14 @@
//! ```
//!
use crate::node::lp::data::handler::pipeline::{MixnodeDataPipeline, MixnodeDataPipelineConfig};
use crate::node::lp::data::handler::pipeline::MixnodeDataPipeline;
use crate::node::lp::data::shared::SharedLpDataState;
use nym_lp_data::AddressedTimedData;
use nym_lp_data::mixnodes::traits::MixnodeProcessingPipeline;
use nym_lp_data::packet::EncryptedLpPacket;
use nym_metrics::inc;
use rand::rngs::OsRng;
use std::sync::mpsc;
use std::sync::{Arc, mpsc};
use std::time::Instant;
use std::{net::SocketAddr, time::Duration};
use tokio::sync::mpsc::error::TrySendError;
@@ -35,10 +35,12 @@ mod pipeline;
mod processing;
const PIPELINE_TICKING_DURATION: Duration = Duration::from_millis(1);
const FRAGMENT_TIMEOUT_DURATION: Duration = Duration::from_secs(30);
/// LP Data Handler for UDP data plane, act as a pipeline driver and buffer for delaying packet
pub struct LpDataHandler {
/// Shared state
_shared_state: Arc<SharedLpDataState>,
/// Channel to receive incoming data
input_rx: mpsc::Receiver<EncryptedLpPacket>,
@@ -60,16 +62,12 @@ impl LpDataHandler {
output_tx: tokio::sync::mpsc::Sender<(EncryptedLpPacket, SocketAddr)>,
shutdown: nym_task::ShutdownToken,
) -> Self {
let shared_state = Arc::new(state);
Self {
_shared_state: shared_state.clone(),
input_rx,
output_tx,
pipeline: MixnodeDataPipeline::new(
state,
MixnodeDataPipelineConfig {
fragment_timeout: FRAGMENT_TIMEOUT_DURATION,
},
OsRng,
),
pipeline: MixnodeDataPipeline::new(shared_state, OsRng),
outgoing_pkt_buffer: Vec::new(),
shutdown,
}
+7 -21
View File
@@ -1,10 +1,7 @@
// Copyright 2026 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use std::{
net::SocketAddr,
time::{Duration, Instant},
};
use std::{net::SocketAddr, sync::Arc, time::Instant};
use nym_lp_data::{
AddressedTimedData, PipelinePayload, TimedData, TimedPayload,
@@ -12,7 +9,7 @@ use nym_lp_data::{
Framing, FramingUnwrap, Transport, TransportUnwrap, WireUnwrappingPipeline,
WireWrappingPipeline,
},
fragmentation::{fragment::fragment_payload, reconstruction::MessageReconstructor},
fragmentation::fragment::fragment_payload,
mixnodes::traits::MixnodeProcessingPipeline,
packet::{
EncryptedLpPacket, LpFrame, LpHeader, LpPacket, MalformedLpPacketError,
@@ -27,19 +24,12 @@ use crate::node::lp::data::{
shared::SharedLpDataState,
};
#[derive(Clone, Copy, Debug)]
pub struct MixnodeDataPipelineConfig {
pub fragment_timeout: Duration,
}
pub struct MixnodeDataPipeline<R>
where
R: Rng,
{
config: MixnodeDataPipelineConfig,
/// Shared data state
state: SharedLpDataState,
fragment_reconstructor: MessageReconstructor<Instant, Duration>,
state: Arc<SharedLpDataState>,
rng: R,
}
@@ -47,13 +37,8 @@ impl<R> MixnodeDataPipeline<R>
where
R: Rng,
{
pub fn new(state: SharedLpDataState, config: MixnodeDataPipelineConfig, rng: R) -> Self {
Self {
state,
config,
rng,
fragment_reconstructor: MessageReconstructor::new(config.fragment_timeout),
}
pub fn new(state: Arc<SharedLpDataState>, rng: R) -> Self {
Self { state, rng }
}
}
@@ -190,7 +175,8 @@ where
.inspect_err(|e| tracing::error!("Failed to recover a fragment : {e}"))
.ok()?;
let (payload, metadata) = self
.fragment_reconstructor
.state
.message_reconstructor
.insert_new_fragment(fragment, frame.timestamp)?;
let message_kind = metadata
.try_into()
+5 -17
View File
@@ -6,6 +6,7 @@ use crate::config::LpConfig;
use crate::node::key_rotation::active_keys::ActiveSphinxKeys;
use crate::node::key_rotation::active_keys::SphinxKeyGuard;
use crate::node::replay_protection::bloomfilter::ReplayProtectionBloomfilters;
use nym_lp_data::fragmentation::reconstruction::MessageReconstructor;
use nym_node_metrics::NymNodeMetrics;
use nym_node_metrics::mixnet::PacketKind;
use nym_sphinx_framing::processing::{
@@ -15,35 +16,19 @@ use nym_sphinx_params::SphinxKeyRotation;
use nym_task::ShutdownToken;
use std::net::IpAddr;
use std::time::Duration;
use std::time::Instant;
use tracing::Span;
use tracing::warn;
#[derive(Clone, Copy)]
pub(crate) struct ProcessingConfig {
pub(crate) maximum_packet_delay: Duration,
// /// how long the task is willing to skip mutex acquisition before it will block the thread
// /// until it actually obtains it
// pub(crate) maximum_replay_detection_deferral: Duration,
// /// how many packets the task is willing to queue before it will block the thread
// /// until it obtains the mutex
// pub(crate) maximum_replay_detection_pending_packets: usize,
}
impl ProcessingConfig {
pub(crate) fn new(config: &Config) -> Self {
ProcessingConfig {
maximum_packet_delay: config.mixnet.debug.maximum_forward_packet_delay,
// maximum_replay_detection_deferral: config
// .mixnet
// .replay_protection
// .debug
// .maximum_replay_detection_deferral,
// maximum_replay_detection_pending_packets: config
// .mixnet
// .replay_protection
// .debug
// .maximum_replay_detection_pending_packets,
}
}
}
@@ -60,6 +45,8 @@ pub(crate) struct SharedLpDataState {
pub replay_protection_filter: ReplayProtectionBloomfilters,
pub message_reconstructor: MessageReconstructor<Instant, Duration>,
/// Metrics collection
pub metrics: NymNodeMetrics,
@@ -86,6 +73,7 @@ impl SharedLpDataState {
lp_config: config.lp,
sphinx_keys,
replay_protection_filter,
message_reconstructor: Default::default(),
metrics,
shutdown_token,
}