Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Framing crate refactor: cleanup header.rs and remove Frame trait #976

Merged
merged 2 commits into from
Jul 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion benches/benches/src/sv2/criterion_sv2_benchmark.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use codec_sv2::{Frame, StandardEitherFrame, StandardSv2Frame};
use codec_sv2::{StandardEitherFrame, StandardSv2Frame};
use criterion::{black_box, Criterion};
use roles_logic_sv2::{
handlers::{common::ParseUpstreamCommonMessages, mining::ParseUpstreamMiningMessages},
Expand Down
2 changes: 1 addition & 1 deletion benches/benches/src/sv2/iai_sv2_benchmark.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use codec_sv2::{Frame, StandardEitherFrame, StandardSv2Frame};
use codec_sv2::{StandardEitherFrame, StandardSv2Frame};
use iai::{black_box, main};
use roles_logic_sv2::{
handlers::{common::ParseUpstreamCommonMessages, mining::ParseUpstreamMiningMessages, SendTo_},
Expand Down
2 changes: 1 addition & 1 deletion examples/interop-cpp/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ mod main_ {

#[cfg(not(feature = "with_serde"))]
mod main_ {
use codec_sv2::{Encoder, Frame, StandardDecoder, StandardSv2Frame};
use codec_sv2::{Encoder, StandardDecoder, StandardSv2Frame};
use common_messages_sv2::{Protocol, SetupConnection, SetupConnectionError};
use const_sv2::{
CHANNEL_BIT_SETUP_CONNECTION, MESSAGE_TYPE_SETUP_CONNECTION,
Expand Down
2 changes: 1 addition & 1 deletion examples/ping-pong-with-noise/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use async_std::{
};
use core::convert::TryInto;

use codec_sv2::{Frame, HandshakeRole, StandardEitherFrame, StandardSv2Frame};
use codec_sv2::{HandshakeRole, StandardEitherFrame, StandardSv2Frame};

use std::time;

Expand Down
2 changes: 1 addition & 1 deletion examples/ping-pong-without-noise/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use async_std::{
task,
};

use codec_sv2::{Frame, StandardDecoder, StandardSv2Frame};
use codec_sv2::{StandardDecoder, StandardSv2Frame};

#[derive(Debug)]
enum Expected {
Expand Down
2 changes: 1 addition & 1 deletion examples/template-provider-test/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use async_channel::{Receiver, Sender};
use async_std::net::TcpStream;
use codec_sv2::{Frame, StandardEitherFrame, StandardSv2Frame, Sv2Frame};
use codec_sv2::{StandardEitherFrame, StandardSv2Frame, Sv2Frame};
use network_helpers::PlainConnection;
use roles_logic_sv2::{
parsers::{IsSv2Message, TemplateDistribution},
Expand Down
2 changes: 1 addition & 1 deletion protocols/fuzz-tests/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
use libfuzzer_sys::fuzz_target;
use binary_codec_sv2::{Seq064K,U256,B0255,Seq0255};
use binary_codec_sv2::from_bytes;
use codec_sv2::{StandardDecoder,Sv2Frame,Frame};
use codec_sv2::{StandardDecoder,Sv2Frame};
use roles_logic_sv2::parsers::PoolMessages;

type F = Sv2Frame<PoolMessages<'static>,Vec<u8>>;
Expand Down
20 changes: 10 additions & 10 deletions protocols/v2/codec-sv2/src/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ use core::marker::PhantomData;
#[cfg(feature = "noise_sv2")]
use framing_sv2::framing2::HandShakeFrame;
#[cfg(feature = "noise_sv2")]
use framing_sv2::header::NoiseHeader;
use framing_sv2::header::{NOISE_HEADER_ENCRYPTED_SIZE, NOISE_HEADER_SIZE};
use framing_sv2::{
framing2::{EitherFrame, Frame as F_, Sv2Frame},
framing2::{EitherFrame, Sv2Frame},
header::Header,
};
#[cfg(feature = "noise_sv2")]
Expand Down Expand Up @@ -58,7 +58,7 @@ impl<'a, T: Serialize + GetSize + Deserialize<'a>, B: IsBuffer + AeadBuffer> Wit
let hint = *msg_len - self.noise_buffer.as_ref().len();
match hint {
0 => {
self.missing_noise_b = NoiseHeader::HEADER_SIZE;
self.missing_noise_b = NOISE_HEADER_SIZE;
Ok(self.while_handshaking())
}
_ => {
Expand All @@ -71,20 +71,20 @@ impl<'a, T: Serialize + GetSize + Deserialize<'a>, B: IsBuffer + AeadBuffer> Wit
let hint = if IsBuffer::len(&self.sv2_buffer) < SV2_FRAME_HEADER_SIZE {
let len = IsBuffer::len(&self.noise_buffer);
let src = self.noise_buffer.get_data_by_ref(len);
if src.len() < NoiseHeader::SIZE {
NoiseHeader::SIZE - src.len()
if src.len() < NOISE_HEADER_ENCRYPTED_SIZE {
NOISE_HEADER_ENCRYPTED_SIZE - src.len()
} else {
0
}
} else {
let src = self.sv2_buffer.get_data_by_ref_(SV2_FRAME_HEADER_SIZE);
let src = self.sv2_buffer.get_data_by_ref(SV2_FRAME_HEADER_SIZE);
let header = Header::from_bytes(src)?;
header.encrypted_len() - IsBuffer::len(&self.noise_buffer)
};

match hint {
0 => {
self.missing_noise_b = NoiseHeader::SIZE;
self.missing_noise_b = NOISE_HEADER_ENCRYPTED_SIZE;
self.decode_noise_frame(noise_codec)
}
_ => {
Expand All @@ -106,14 +106,14 @@ impl<'a, T: Serialize + GetSize + Deserialize<'a>, B: IsBuffer + AeadBuffer> Wit
IsBuffer::len(&self.sv2_buffer),
) {
// HERE THE SV2 HEADER IS READY TO BE DECRYPTED
(NoiseHeader::SIZE, 0) => {
(NOISE_HEADER_ENCRYPTED_SIZE, 0) => {
let src = self.noise_buffer.get_data_owned();
let decrypted_header = self.sv2_buffer.get_writable(NoiseHeader::SIZE);
let decrypted_header = self.sv2_buffer.get_writable(NOISE_HEADER_ENCRYPTED_SIZE);
decrypted_header.copy_from_slice(src.as_ref());
self.sv2_buffer.as_ref();
noise_codec.decrypt(&mut self.sv2_buffer)?;
let header =
Header::from_bytes(self.sv2_buffer.get_data_by_ref_(SV2_FRAME_HEADER_SIZE))?;
Header::from_bytes(self.sv2_buffer.get_data_by_ref(SV2_FRAME_HEADER_SIZE))?;
self.missing_noise_b = header.encrypted_len();
Err(Error::MissingBytes(header.encrypted_len()))
}
Expand Down
6 changes: 3 additions & 3 deletions protocols/v2/codec-sv2/src/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ pub use const_sv2::{AEAD_MAC_LEN, SV2_FRAME_CHUNK_SIZE, SV2_FRAME_HEADER_SIZE};
#[cfg(feature = "noise_sv2")]
use core::convert::TryInto;
use core::marker::PhantomData;
use framing_sv2::framing2::Sv2Frame;
#[cfg(feature = "noise_sv2")]
use framing_sv2::framing2::{EitherFrame, HandShakeFrame};
use framing_sv2::framing2::{Frame as F_, Sv2Frame};
#[allow(unused_imports)]
pub use framing_sv2::header::NoiseHeader;
pub use framing_sv2::header::NOISE_HEADER_ENCRYPTED_SIZE;

#[cfg(feature = "noise_sv2")]
use tracing::error;
Expand Down Expand Up @@ -76,7 +76,7 @@ impl<T: Serialize + GetSize> NoiseEncoder<T> {
} else {
SV2_FRAME_CHUNK_SIZE + start - AEAD_MAC_LEN
};
let mut encrypted_len = NoiseHeader::SIZE;
let mut encrypted_len = NOISE_HEADER_ENCRYPTED_SIZE;

while start < sv2.len() {
let to_encrypt = self.noise_buffer.get_writable(end - start);
Expand Down
2 changes: 1 addition & 1 deletion protocols/v2/codec-sv2/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub use encoder::NoiseEncoder;

#[cfg(feature = "noise_sv2")]
pub use framing_sv2::framing2::HandShakeFrame;
pub use framing_sv2::framing2::{Frame, Sv2Frame};
pub use framing_sv2::framing2::Sv2Frame;

#[cfg(feature = "noise_sv2")]
pub use noise_sv2::{self, Initiator, NoiseCodec, Responder};
Expand Down
9 changes: 7 additions & 2 deletions protocols/v2/framing-sv2/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,13 @@ impl fmt::Display for Error {
ExpectedSv2Frame => {
write!(f, "Expected `Sv2Frame`, received `HandshakeFrame`")
}
UnexpectedHeaderLength(i) => {
write!(f, "Unexpected `Header` length: `{}`", i)
UnexpectedHeaderLength(actual_size) => {
write!(
f,
"Unexpected `Header` length: `{}`, should be equal or more to {}",
actual_size,
const_sv2::SV2_FRAME_HEADER_SIZE
)
}
}
}
Expand Down
102 changes: 21 additions & 81 deletions protocols/v2/framing-sv2/src/framing2.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#![allow(dead_code)]
use crate::{
header::{Header, NoiseHeader},
header::{Header, NOISE_HEADER_LEN_OFFSET, NOISE_HEADER_SIZE},
Error,
};
use alloc::vec::Vec;
Expand Down Expand Up @@ -29,51 +30,6 @@ impl<A, B> Sv2Frame<A, B> {
}
}

pub trait Frame<'a, T: Serialize + GetSize>: Sized {
type Buffer: AsMut<[u8]>;
type Deserialized;

/// Write the serialized `Frame` into `dst`.
fn serialize(self, dst: &mut [u8]) -> Result<(), Error>;

/// Get the payload
fn payload(&'a mut self) -> &'a mut [u8];

/// Returns `Some(self.header)` when the frame has a header (`Sv2Frame`), returns `None` where it doesn't (`HandShakeFrame`).
fn get_header(&self) -> Option<crate::header::Header>;

/// Try to build a `Frame` from raw bytes.
/// Checks if the payload has the correct size (as stated in the `Header`).
/// Returns `Self` on success, or the number of the bytes needed to complete the frame
/// as an error. Nothing is assumed or checked about the correctness of the payload.
fn from_bytes(bytes: Self::Buffer) -> Result<Self, isize>;

/// Builds a `Frame` from raw bytes.
/// Does not check if the payload has the correct size (as stated in the `Header`).
/// Nothing is assumed or checked about the correctness of the payload.
fn from_bytes_unchecked(bytes: Self::Buffer) -> Self;

/// Helps to determine if the frame size encoded in a byte array correctly representing the size of the frame.
/// - Returns `0` if the byte slice is of the expected size according to the header.
/// - Returns a negative value if the byte slice is smaller than a Noise Frame header; this value
/// represents how many bytes are missing.
/// - Returns a positive value if the byte slice is longer than expected; this value
/// indicates the surplus of bytes beyond the expected size.
fn size_hint(bytes: &[u8]) -> isize;

/// Returns the size of the `Frame` payload.
fn encoded_length(&self) -> usize;

/// Try to build a `Frame` from a serializable payload.
/// Returns `Some(Self)` if the size of the payload fits in the frame, `None` otherwise.
fn from_message(
message: T,
message_type: u8,
extension_type: u16,
channel_msg: bool,
) -> Option<Self>;
}

/// Abstraction for a SV2 Frame.
#[derive(Debug, Clone)]
pub struct Sv2Frame<T, B> {
Expand All @@ -83,16 +39,6 @@ pub struct Sv2Frame<T, B> {
serialized: Option<B>,
}

impl<T, B> Default for Sv2Frame<T, B> {
fn default() -> Self {
Sv2Frame {
header: Header::default(),
payload: None,
serialized: None,
}
}
}

/// Abstraction for a Noise Handshake Frame
/// Contains only a `Slice` payload with a fixed length
/// Only used during Noise Handshake process
Expand All @@ -108,15 +54,12 @@ impl HandShakeFrame {
}
}

impl<'a, T: Serialize + GetSize, B: AsMut<[u8]> + AsRef<[u8]>> Frame<'a, T> for Sv2Frame<T, B> {
type Buffer = B;
type Deserialized = B;

impl<T: Serialize + GetSize, B: AsMut<[u8]> + AsRef<[u8]>> Sv2Frame<T, B> {
/// Write the serialized `Sv2Frame` into `dst`.
/// This operation when called on an already serialized frame is very cheap.
/// When called on a non serialized frame, it is not so cheap (because it serializes it).
#[inline]
fn serialize(self, dst: &mut [u8]) -> Result<(), Error> {
pub fn serialize(self, dst: &mut [u8]) -> Result<(), Error> {
if let Some(mut serialized) = self.serialized {
dst.swap_with_slice(serialized.as_mut());
Ok(())
Expand All @@ -142,7 +85,7 @@ impl<'a, T: Serialize + GetSize, B: AsMut<[u8]> + AsRef<[u8]>> Frame<'a, T> for
/// This function is only intended as a fast way to get a reference to an
/// already serialized payload. If the frame has not yet been
/// serialized, this function should never be used (it will panic).
fn payload(&'a mut self) -> &'a mut [u8] {
pub fn payload(&mut self) -> &mut [u8] {
if let Some(serialized) = self.serialized.as_mut() {
&mut serialized.as_mut()[Header::SIZE..]
} else {
Expand All @@ -152,15 +95,15 @@ impl<'a, T: Serialize + GetSize, B: AsMut<[u8]> + AsRef<[u8]>> Frame<'a, T> for
}

/// `Sv2Frame` always returns `Some(self.header)`.
fn get_header(&self) -> Option<crate::header::Header> {
pub fn get_header(&self) -> Option<crate::header::Header> {
Some(self.header)
}

/// Tries to build a `Sv2Frame` from raw bytes, assuming they represent a serialized `Sv2Frame` frame (`Self.serialized`).
/// Returns a `Sv2Frame` on success, or the number of the bytes needed to complete the frame
/// as an error. `Self.serialized` is `Some`, but nothing is assumed or checked about the correctness of the payload.
#[inline]
fn from_bytes(mut bytes: Self::Buffer) -> Result<Self, isize> {
pub fn from_bytes(mut bytes: B) -> Result<Self, isize> {
let hint = Self::size_hint(bytes.as_mut());

if hint == 0 {
Expand All @@ -171,7 +114,7 @@ impl<'a, T: Serialize + GetSize, B: AsMut<[u8]> + AsRef<[u8]>> Frame<'a, T> for
}

#[inline]
fn from_bytes_unchecked(mut bytes: Self::Buffer) -> Self {
pub fn from_bytes_unchecked(mut bytes: B) -> Self {
// Unchecked function caller is supposed to already know that the passed bytes are valid
let header = Header::from_bytes(bytes.as_mut()).expect("Invalid header");
Self {
Expand All @@ -189,7 +132,7 @@ impl<'a, T: Serialize + GetSize, B: AsMut<[u8]> + AsRef<[u8]>> Frame<'a, T> for
/// - Returns a positive value if the byte slice is longer than expected; this value
/// indicates the surplus of bytes beyond the expected size.
#[inline]
fn size_hint(bytes: &[u8]) -> isize {
pub fn size_hint(bytes: &[u8]) -> isize {
match Header::from_bytes(bytes) {
Err(_) => {
// Returns how many bytes are missing from the expected frame size
Expand All @@ -210,7 +153,7 @@ impl<'a, T: Serialize + GetSize, B: AsMut<[u8]> + AsRef<[u8]>> Frame<'a, T> for
/// If `Sv2Frame` is serialized, returns the length of `self.serialized`,
/// otherwise, returns the length of `self.payload`.
#[inline]
fn encoded_length(&self) -> usize {
pub fn encoded_length(&self) -> usize {
if let Some(serialized) = self.serialized.as_ref() {
serialized.as_ref().len()
} else if let Some(payload) = self.payload.as_ref() {
Expand All @@ -223,7 +166,7 @@ impl<'a, T: Serialize + GetSize, B: AsMut<[u8]> + AsRef<[u8]>> Frame<'a, T> for

/// Tries to build a `Sv2Frame` from a non-serialized payload.
/// Returns a `Sv2Frame` if the size of the payload fits in the frame, `None` otherwise.
fn from_message(
pub fn from_message(
message: T,
message_type: u8,
extension_type: u16,
Expand All @@ -239,10 +182,7 @@ impl<'a, T: Serialize + GetSize, B: AsMut<[u8]> + AsRef<[u8]>> Frame<'a, T> for
}
}

impl<'a> Frame<'a, Slice> for HandShakeFrame {
type Buffer = Slice;
type Deserialized = &'a mut [u8];

impl HandShakeFrame {
/// Put the Noise Frame payload into `dst`
#[inline]
fn serialize(mut self, dst: &mut [u8]) -> Result<(), Error> {
Expand All @@ -252,8 +192,8 @@ impl<'a> Frame<'a, Slice> for HandShakeFrame {

/// Get the Noise Frame payload
#[inline]
fn payload(&'a mut self) -> &'a mut [u8] {
&mut self.payload[NoiseHeader::HEADER_SIZE..]
fn payload(&mut self) -> &mut [u8] {
&mut self.payload[NOISE_HEADER_SIZE..]
}

/// `HandShakeFrame` always returns `None`.
Expand All @@ -262,12 +202,12 @@ impl<'a> Frame<'a, Slice> for HandShakeFrame {
}

/// Builds a `HandShakeFrame` from raw bytes. Nothing is assumed or checked about the correctness of the payload.
fn from_bytes(bytes: Self::Buffer) -> Result<Self, isize> {
pub fn from_bytes(bytes: Slice) -> Result<Self, isize> {
Ok(Self::from_bytes_unchecked(bytes))
}

#[inline]
fn from_bytes_unchecked(bytes: Self::Buffer) -> Self {
pub fn from_bytes_unchecked(bytes: Slice) -> Self {
Self { payload: bytes }
}

Expand All @@ -280,17 +220,17 @@ impl<'a> Frame<'a, Slice> for HandShakeFrame {
/// indicates the surplus of bytes beyond the expected size.
#[inline]
fn size_hint(bytes: &[u8]) -> isize {
if bytes.len() < NoiseHeader::HEADER_SIZE {
return (NoiseHeader::HEADER_SIZE - bytes.len()) as isize;
if bytes.len() < NOISE_HEADER_SIZE {
return (NOISE_HEADER_SIZE - bytes.len()) as isize;
};

let len_b = &bytes[NoiseHeader::LEN_OFFSET..NoiseHeader::HEADER_SIZE];
let len_b = &bytes[NOISE_HEADER_LEN_OFFSET..NOISE_HEADER_SIZE];
let expected_len = u16::from_le_bytes([len_b[0], len_b[1]]) as usize;

if bytes.len() - NoiseHeader::HEADER_SIZE == expected_len {
if bytes.len() - NOISE_HEADER_SIZE == expected_len {
0
} else {
expected_len as isize - (bytes.len() - NoiseHeader::HEADER_SIZE) as isize
expected_len as isize - (bytes.len() - NOISE_HEADER_SIZE) as isize
}
}

Expand Down
Loading
Loading