feature: allow nym-nodes to understand future version of sphinx packets (#5496) (#5518)

* use updated sphinx crate

* updated outfox usage of keygen in tests

* use x25519 in outfox

* remove redundant constructor

* adjusted key convertion traits
This commit is contained in:
Jędrzej Stuczyński
2025-02-26 09:47:57 +00:00
committed by GitHub
parent 26f97d3c34
commit 8f5457e698
26 changed files with 489 additions and 768 deletions
@@ -43,6 +43,15 @@ impl OnUpdateMetricsHandler for PrometheusGlobalNodeMetricsRegistryUpdater {
// # MIXNET
// ## INGRESS
for version_entry in self.metrics.mixnet.ingress.packet_versions() {
self.prometheus_wrapper.set(
MixnetIngressPacketVersion {
kind: *version_entry.key(),
},
*version_entry.value(),
)
}
self.prometheus_wrapper.set(
MixnetIngressForwardPacketsReceived,
self.metrics.mixnet.ingress.forward_hop_packets_received() as i64,
+12 -9
View File
@@ -8,7 +8,7 @@ use nym_sphinx_forwarding::packet::MixPacket;
use nym_sphinx_framing::codec::NymCodec;
use nym_sphinx_framing::packet::FramedNymPacket;
use nym_sphinx_framing::processing::{
process_framed_packet, MixProcessingResult, ProcessedFinalHop,
process_framed_packet, MixProcessingResultData, ProcessedFinalHop,
};
use nym_sphinx_types::Delay;
use std::net::SocketAddr;
@@ -44,7 +44,7 @@ impl ConnectionHandler {
ConnectionHandler {
shared: SharedData {
processing_config: shared.processing_config,
sphinx_key: shared.sphinx_key.clone(),
sphinx_keys: shared.sphinx_keys.clone(),
mixnet_forwarder: shared.mixnet_forwarder.clone(),
final_hop: shared.final_hop.clone(),
metrics: shared.metrics.clone(),
@@ -135,7 +135,8 @@ impl ConnectionHandler {
nanos!("handle_received_nym_packet", {
// 1. attempt to unwrap the packet
let unwrapped_packet = process_framed_packet(packet, &self.shared.sphinx_key);
let unwrapped_packet =
process_framed_packet(packet, self.shared.sphinx_keys.private_key().as_ref());
// 2. increment our favourite metrics stats
self.shared
@@ -144,12 +145,14 @@ impl ConnectionHandler {
// 3. forward the packet to the relevant sink (if enabled)
match unwrapped_packet {
Err(err) => trace!("failed to process received mix packet: {err}"),
Ok(MixProcessingResult::ForwardHop(forward_packet, delay)) => {
self.handle_forward_packet(forward_packet, delay);
}
Ok(MixProcessingResult::FinalHop(final_hop_data)) => {
self.handle_final_hop(final_hop_data).await;
}
Ok(processed_packet) => match processed_packet.processing_data {
MixProcessingResultData::ForwardHop { packet, delay } => {
self.handle_forward_packet(packet, delay);
}
MixProcessingResultData::FinalHop { final_hop_data } => {
self.handle_final_hop(final_hop_data).await;
}
},
}
})
}
+28 -11
View File
@@ -7,9 +7,12 @@ use crate::node::mixnet::SharedFinalHopData;
use nym_crypto::asymmetric::x25519;
use nym_gateway::node::GatewayStorageError;
use nym_mixnet_client::forwarder::{MixForwardingSender, PacketToForward};
use nym_node_metrics::mixnet::PacketKind;
use nym_node_metrics::NymNodeMetrics;
use nym_sphinx_forwarding::packet::MixPacket;
use nym_sphinx_framing::processing::{MixProcessingResult, PacketProcessingError};
use nym_sphinx_framing::processing::{
MixPacketVersion, MixProcessingResult, MixProcessingResultData, PacketProcessingError,
};
use nym_sphinx_types::DestinationAddressBytes;
use nym_task::ShutdownToken;
use std::io;
@@ -45,8 +48,7 @@ impl ProcessingConfig {
// explicitly do NOT derive clone as we want to manually apply relevant suffixes to the task clients
pub(crate) struct SharedData {
pub(super) processing_config: ProcessingConfig,
// TODO: this type is not `Zeroize` : (
pub(super) sphinx_key: Arc<nym_sphinx_types::PrivateKey>,
pub(super) sphinx_keys: Arc<x25519::KeyPair>,
// used for FORWARD mix packets and FINAL ack packets
pub(super) mixnet_forwarder: MixForwardingSender,
@@ -58,10 +60,17 @@ pub(crate) struct SharedData {
pub(super) shutdown: ShutdownToken,
}
fn convert_to_metrics_version(processed: MixPacketVersion) -> PacketKind {
match processed {
MixPacketVersion::Outfox => PacketKind::Outfox,
MixPacketVersion::Sphinx(sphinx_version) => PacketKind::Sphinx(sphinx_version.value()),
}
}
impl SharedData {
pub(crate) fn new(
processing_config: ProcessingConfig,
x25519_key: &x25519::PrivateKey,
x25519_keys: Arc<x25519::KeyPair>,
mixnet_forwarder: MixForwardingSender,
final_hop: SharedFinalHopData,
metrics: NymNodeMetrics,
@@ -69,7 +78,7 @@ impl SharedData {
) -> Self {
SharedData {
processing_config,
sphinx_key: Arc::new(x25519_key.into()),
sphinx_keys: x25519_keys,
mixnet_forwarder,
final_hop,
metrics,
@@ -99,10 +108,18 @@ impl SharedData {
processing_result: &Result<MixProcessingResult, PacketProcessingError>,
source: IpAddr,
) {
match processing_result {
Err(_) => self.metrics.mixnet.ingress_malformed_packet(source),
Ok(MixProcessingResult::ForwardHop(_, delay)) => {
self.metrics.mixnet.ingress_received_forward_packet(source);
let Ok(processing_result) = processing_result else {
self.metrics.mixnet.ingress_malformed_packet(source);
return;
};
let packet_version = convert_to_metrics_version(processing_result.packet_version);
match processing_result.processing_data {
MixProcessingResultData::ForwardHop { delay, .. } => {
self.metrics
.mixnet
.ingress_received_forward_packet(source, packet_version);
// check if the delay wasn't excessive
if let Some(delay) = delay {
@@ -111,10 +128,10 @@ impl SharedData {
}
}
}
Ok(MixProcessingResult::FinalHop(_)) => {
MixProcessingResultData::FinalHop { .. } => {
self.metrics
.mixnet
.ingress_received_final_hop_packet(source);
.ingress_received_final_hop_packet(source, packet_version);
}
}
}
+1 -1
View File
@@ -993,7 +993,7 @@ impl NymNode {
let shared = mixnet::SharedData::new(
processing_config,
self.x25519_sphinx_keys.private_key(),
self.x25519_sphinx_keys.clone(),
mix_packet_sender.clone(),
final_hop_data,
self.metrics.clone(),