More work on the reciever end, and outfox format

This commit is contained in:
durch
2023-05-04 16:08:46 +02:00
parent 4d837a0402
commit 19c4b3255c
37 changed files with 1234 additions and 1622 deletions
@@ -10,7 +10,7 @@ use nym_sphinx_forwarding::packet::MixPacket;
use nym_sphinx_framing::packet::FramedNymPacket;
use nym_sphinx_params::{PacketSize, PacketType};
use nym_sphinx_types::{
Delay as SphinxDelay, DestinationAddressBytes, NodeAddressBytes, NymPacket, Payload,
Delay as SphinxDelay, DestinationAddressBytes, NodeAddressBytes, NymPacket, NymProcessedPacket,
PrivateKey, ProcessedPacket,
};
use std::convert::TryFrom;
@@ -56,10 +56,10 @@ impl SphinxPacketProcessor {
fn perform_initial_packet_processing(
&self,
packet: NymPacket,
) -> Result<ProcessedPacket, MixProcessingError> {
) -> Result<NymProcessedPacket, MixProcessingError> {
measure!({
packet.process(&self.sphinx_key).map_err(|err| {
debug!("Failed to unwrap Sphinx packet: {err}");
info!("Failed to unwrap NymPacket packet: {err}");
MixProcessingError::NymPacketProcessingError(err)
})
})
@@ -73,7 +73,7 @@ impl SphinxPacketProcessor {
fn perform_initial_unwrapping(
&self,
received: FramedNymPacket,
) -> Result<ProcessedPacket, MixProcessingError> {
) -> Result<NymProcessedPacket, MixProcessingError> {
measure!({
let packet = received.into_inner();
@@ -101,14 +101,17 @@ impl SphinxPacketProcessor {
fn split_hop_data_into_ack_and_message(
&self,
mut extracted_data: Vec<u8>,
packet_type: PacketType,
) -> Result<(Vec<u8>, Vec<u8>), MixProcessingError> {
let ack_len = SurbAck::len(Some(packet_type));
// in theory it's impossible for this to fail since it managed to go into correct `match`
// branch at the caller
if extracted_data.len() < SurbAck::len() {
if extracted_data.len() < ack_len {
return Err(MixProcessingError::NoSurbAckInFinalHop);
}
let message = extracted_data.split_off(SurbAck::len());
let message = extracted_data.split_off(ack_len);
let ack_data = extracted_data;
Ok((ack_data, message))
}
@@ -130,13 +133,18 @@ impl SphinxPacketProcessor {
| PacketSize::ExtendedPacket8
| PacketSize::ExtendedPacket16
| PacketSize::ExtendedPacket32
| PacketSize::OutfoxRegularPacket
| PacketSize::OutfoxExtendedPacket8
| PacketSize::OutfoxExtendedPacket16
| PacketSize::OutfoxExtendedPacket32 => {
| PacketSize::OutfoxRegularPacket => {
trace!("received a normal packet!");
let (ack_data, message) = self.split_hop_data_into_ack_and_message(data)?;
let (ack_first_hop, ack_packet) = SurbAck::try_recover_first_hop_packet(&ack_data)?;
let (ack_data, message) =
self.split_hop_data_into_ack_and_message(data, packet_type)?;
let (ack_first_hop, ack_packet) =
match SurbAck::try_recover_first_hop_packet(&ack_data, packet_type) {
Ok((first_hop, packet)) => (first_hop, packet),
Err(err) => {
error!("Failed to recover first hop from ack data: {err}");
return Err(err.into());
}
};
let forward_ack = MixPacket::new(ack_first_hop, ack_packet, packet_type);
Ok((Some(forward_ack), message))
}
@@ -149,14 +157,12 @@ impl SphinxPacketProcessor {
fn process_final_hop(
&self,
destination: DestinationAddressBytes,
payload: Payload,
payload: Vec<u8>,
packet_size: PacketSize,
packet_type: PacketType,
) -> Result<MixProcessingResult, MixProcessingError> {
let packet_message = payload.recover_plaintext()?;
let (forward_ack, message) =
self.split_into_ack_and_message(packet_message, packet_size, packet_type)?;
self.split_into_ack_and_message(payload, packet_size, packet_type)?;
Ok(MixProcessingResult::FinalHop(ProcessedFinalHop {
destination,
@@ -169,18 +175,48 @@ impl SphinxPacketProcessor {
/// or a final hop.
fn perform_final_processing(
&self,
packet: ProcessedPacket,
packet: NymProcessedPacket,
packet_size: PacketSize,
packet_type: PacketType,
) -> Result<MixProcessingResult, MixProcessingError> {
match packet {
ProcessedPacket::ForwardHop(packet, address, delay) => {
self.process_forward_hop(NymPacket::Sphinx(*packet), address, delay, packet_type)
NymProcessedPacket::Sphinx(packet) => {
match packet {
ProcessedPacket::ForwardHop(packet, address, delay) => self
.process_forward_hop(
NymPacket::Sphinx(*packet),
address,
delay,
packet_type,
),
// right now there's no use for the surb_id included in the header - probably it should get removed from the
// sphinx all together?
ProcessedPacket::FinalHop(destination, _, payload) => self.process_final_hop(
destination,
payload.recover_plaintext()?,
packet_size,
packet_type,
),
}
}
// right now there's no use for the surb_id included in the header - probably it should get removed from the
// sphinx all together?
ProcessedPacket::FinalHop(destination, _, payload) => {
self.process_final_hop(destination, payload, packet_size, packet_type)
NymProcessedPacket::Outfox(packet) => {
let next_address = *packet.next_address();
let packet = packet.into_packet();
if packet.is_final_hop() {
self.process_final_hop(
DestinationAddressBytes::from_bytes(next_address),
packet.recover_plaintext().to_vec(),
packet_size,
packet_type,
)
} else {
let mix_packet = MixPacket::new(
NymNodeRoutingAddress::try_from_bytes(&next_address)?,
NymPacket::Outfox(packet),
PacketType::Outfox,
);
Ok(MixProcessingResult::ForwardHop(mix_packet, None))
}
}
}
}
@@ -225,31 +261,71 @@ mod tests {
let short_data = vec![42u8];
assert!(processor
.split_hop_data_into_ack_and_message(short_data)
.split_hop_data_into_ack_and_message(short_data, PacketType::Mix)
.is_err());
let sufficient_data = vec![42u8; SurbAck::len()];
let sufficient_data = vec![42u8; SurbAck::len(Some(PacketType::Mix))];
let (ack, data) = processor
.split_hop_data_into_ack_and_message(sufficient_data.clone())
.split_hop_data_into_ack_and_message(sufficient_data.clone(), PacketType::Mix)
.unwrap();
assert_eq!(sufficient_data, ack);
assert!(data.is_empty());
let long_data = vec![42u8; SurbAck::len() * 5];
let long_data = vec![42u8; SurbAck::len(Some(PacketType::Mix)) * 5];
let (ack, data) = processor
.split_hop_data_into_ack_and_message(long_data)
.split_hop_data_into_ack_and_message(long_data, PacketType::Mix)
.unwrap();
assert_eq!(ack.len(), SurbAck::len());
assert_eq!(data.len(), SurbAck::len() * 4)
assert_eq!(ack.len(), SurbAck::len(Some(PacketType::Mix)));
assert_eq!(data.len(), SurbAck::len(Some(PacketType::Mix)) * 4)
}
#[tokio::test]
async fn splitting_hop_data_works_for_sufficiently_long_payload_outfox() {
let processor = fixture();
let short_data = vec![42u8];
assert!(processor
.split_hop_data_into_ack_and_message(short_data, PacketType::Outfox)
.is_err());
let sufficient_data = vec![42u8; SurbAck::len(Some(PacketType::Outfox))];
let (ack, data) = processor
.split_hop_data_into_ack_and_message(sufficient_data.clone(), PacketType::Outfox)
.unwrap();
assert_eq!(sufficient_data, ack);
assert!(data.is_empty());
let long_data = vec![42u8; SurbAck::len(Some(PacketType::Outfox)) * 5];
let (ack, data) = processor
.split_hop_data_into_ack_and_message(long_data, PacketType::Outfox)
.unwrap();
assert_eq!(ack.len(), SurbAck::len(Some(PacketType::Outfox)));
assert_eq!(data.len(), SurbAck::len(Some(PacketType::Outfox)) * 4)
}
#[tokio::test]
async fn splitting_into_ack_and_message_returns_whole_data_for_ack() {
let processor = fixture();
let data = vec![42u8; SurbAck::len() + 10];
let data = vec![42u8; SurbAck::len(Some(PacketType::Mix)) + 10];
let (ack, message) = processor
.split_into_ack_and_message(data.clone(), PacketSize::AckPacket, Default::default())
.split_into_ack_and_message(data.clone(), PacketSize::AckPacket, PacketType::Mix)
.unwrap();
assert!(ack.is_none());
assert_eq!(data, message)
}
#[tokio::test]
async fn splitting_into_ack_and_message_returns_whole_data_for_ack_outfox() {
let processor = fixture();
let data = vec![42u8; SurbAck::len(Some(PacketType::Outfox)) + 10];
let (ack, message) = processor
.split_into_ack_and_message(
data.clone(),
PacketSize::OutfoxAckPacket,
PacketType::Outfox,
)
.unwrap();
assert!(ack.is_none());
assert_eq!(data, message)