112 lines
3.6 KiB
Rust
112 lines
3.6 KiB
Rust
// Copyright 2026 - Nym Technologies SA <contact@nymtech.net>
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
use nym_lp_data::packet::frame::{LpFrameAttributes, LpFrameHeader, LpFrameKind};
|
|
use nym_node_metrics::mixnet::PacketKind;
|
|
use nym_sphinx_forwarding::packet::MixPacketFormattingError;
|
|
use nym_sphinx_params::SphinxKeyRotation;
|
|
use nym_topology::NodeId;
|
|
|
|
use crate::node::lp::data::handler::{
|
|
error::LpDataHandlerError,
|
|
messages::{MixMessage, SphinxMixMessage},
|
|
};
|
|
|
|
/// Message types supported by nym-nodes with a gateway role.
|
|
#[derive(Debug, Clone, Copy)]
|
|
pub enum NymNodeMessage {
|
|
Mix(MixMessage),
|
|
ForwardSphinx(ForwardSphinxMixMessage),
|
|
ForwardOutfox(ForwardOutfoxMixMessage),
|
|
}
|
|
|
|
impl NymNodeMessage {
|
|
pub fn from_frame_header(header: LpFrameHeader) -> Result<Self, LpDataHandlerError> {
|
|
match header.kind {
|
|
LpFrameKind::SphinxPacket | LpFrameKind::OutfoxPacket => {
|
|
Ok(NymNodeMessage::Mix(MixMessage::from_frame_header(header)?))
|
|
}
|
|
LpFrameKind::ForwardSphinxPacket => Ok(NymNodeMessage::ForwardSphinx(
|
|
header.frame_attributes.try_into()?,
|
|
)),
|
|
LpFrameKind::ForwardOutfoxPacket => Ok(NymNodeMessage::ForwardOutfox(
|
|
header.frame_attributes.try_into()?,
|
|
)),
|
|
_ => Err(LpDataHandlerError::UnsupportedLpFrameKind { typ: header.kind }),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<NymNodeMessage> for PacketKind {
|
|
fn from(value: NymNodeMessage) -> Self {
|
|
match value {
|
|
NymNodeMessage::Mix(msg) => msg.into(),
|
|
NymNodeMessage::ForwardSphinx(_) => PacketKind::LpSphinx,
|
|
NymNodeMessage::ForwardOutfox(_) => PacketKind::LpOutfox,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<MixMessage> for NymNodeMessage {
|
|
fn from(value: MixMessage) -> Self {
|
|
NymNodeMessage::Mix(value)
|
|
}
|
|
}
|
|
|
|
impl From<NymNodeMessage> for LpFrameHeader {
|
|
fn from(value: NymNodeMessage) -> Self {
|
|
match value {
|
|
NymNodeMessage::Mix(msg) => msg.into(),
|
|
NymNodeMessage::ForwardSphinx(msg) => {
|
|
LpFrameHeader::new(LpFrameKind::ForwardSphinxPacket, msg)
|
|
}
|
|
NymNodeMessage::ForwardOutfox(msg) => {
|
|
LpFrameHeader::new(LpFrameKind::ForwardOutfoxPacket, msg)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, Copy)]
|
|
pub struct ForwardSphinxMixMessage {
|
|
pub key_rotation: SphinxKeyRotation,
|
|
pub next_hop: NodeId,
|
|
}
|
|
|
|
impl TryFrom<LpFrameAttributes> for ForwardSphinxMixMessage {
|
|
type Error = LpDataHandlerError;
|
|
|
|
fn try_from(value: LpFrameAttributes) -> Result<Self, Self::Error> {
|
|
let key_rotation = value[0]
|
|
.try_into()
|
|
.map_err(MixPacketFormattingError::InvalidKeyRotation)?;
|
|
// SAFETY : slice to array conversion with correct size
|
|
#[allow(clippy::unwrap_used)]
|
|
let next_hop = NodeId::from_be_bytes(value[1..5].try_into().unwrap());
|
|
Ok(ForwardSphinxMixMessage {
|
|
key_rotation,
|
|
next_hop,
|
|
})
|
|
}
|
|
}
|
|
|
|
impl From<ForwardSphinxMixMessage> for LpFrameAttributes {
|
|
fn from(value: ForwardSphinxMixMessage) -> Self {
|
|
let mut attrs = [0; 14];
|
|
attrs[0] = value.key_rotation as u8;
|
|
attrs[1..5].copy_from_slice(&value.next_hop.to_be_bytes());
|
|
attrs
|
|
}
|
|
}
|
|
|
|
impl From<ForwardSphinxMixMessage> for SphinxMixMessage {
|
|
fn from(value: ForwardSphinxMixMessage) -> Self {
|
|
SphinxMixMessage {
|
|
key_rotation: value.key_rotation,
|
|
}
|
|
}
|
|
}
|
|
|
|
// For now there are no differences. We can augment this variant when we will need it
|
|
pub type ForwardOutfoxMixMessage = ForwardSphinxMixMessage;
|