From 1bc0bd500deb70557b1c9f3a921e1dbbf1cd9c3c Mon Sep 17 00:00:00 2001 From: plebhash Date: Mon, 24 Jun 2024 15:04:12 -0300 Subject: [PATCH 1/9] fix mg submit solution jd --- utils/message-generator/src/parser/sv2_messages.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/utils/message-generator/src/parser/sv2_messages.rs b/utils/message-generator/src/parser/sv2_messages.rs index 4919fc324f..091d0c58cc 100644 --- a/utils/message-generator/src/parser/sv2_messages.rs +++ b/utils/message-generator/src/parser/sv2_messages.rs @@ -372,6 +372,8 @@ pub enum JobDeclaration<'a> { ProvideMissingTransactions(ProvideMissingTransactions<'a>), #[serde(borrow)] ProvideMissingTransactionsSuccess(ProvideMissingTransactionsSuccess<'a>), + #[serde(borrow)] + SubmitSolution(SubmitSolutionJd<'a>), } impl<'a> From> for roles_logic_sv2::parsers::JobDeclaration<'a> { @@ -390,6 +392,7 @@ impl<'a> From> for roles_logic_sv2::parsers::JobDeclaration<' JobDeclaration::ProvideMissingTransactionsSuccess(m) => { Self::ProvideMissingTransactionsSuccess(m) } + JobDeclaration::SubmitSolution(m) => Self::SubmitSolution(m), } } } From 862a25f1fc1239b1ff863bf4eb08ebdcdb7c4e4f Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sat, 29 Jun 2024 23:20:17 -0400 Subject: [PATCH 2/9] Refactor: JobDeclarator redefined last_declare_job sender --- roles/jd-client/src/lib/downstream.rs | 8 ++-- .../src/lib/job_declarator/message_handler.rs | 20 ++++++--- roles/jd-client/src/lib/job_declarator/mod.rs | 42 ++++++++++++------- roles/jd-client/src/lib/mod.rs | 2 +- roles/jd-client/src/main.rs | 14 +++---- 5 files changed, 52 insertions(+), 34 deletions(-) diff --git a/roles/jd-client/src/lib/downstream.rs b/roles/jd-client/src/lib/downstream.rs index ddc6e5bd0f..da14c7b0aa 100644 --- a/roles/jd-client/src/lib/downstream.rs +++ b/roles/jd-client/src/lib/downstream.rs @@ -32,8 +32,8 @@ pub type EitherFrame = StandardEitherFrame; /// 1 to 1 connection with a downstream node that implement the mining (sub)protocol can be either /// a mining device or a downstream proxy. -/// A downstream can only be linked with an upstream at a time. Support multi upstrems for -/// downstream do no make much sense. +/// A downstream can only be linked with an upstream at a time. Support multi upstreams for +/// downstream do not make much sense. #[derive(Debug)] pub struct DownstreamMiningNode { receiver: Receiver, @@ -181,7 +181,7 @@ impl DownstreamMiningNode { } } - /// Send SetupConnectionSuccess to donwstream and start processing new messages coming from + /// Send SetupConnectionSuccess to downstream and start processing new messages coming from /// downstream pub async fn start( self_mutex: &Arc>, @@ -225,7 +225,7 @@ impl DownstreamMiningNode { // mining channel success fn set_channel_factory(self_mutex: Arc>) { if !self_mutex.safe_lock(|s| s.status.is_solo_miner()).unwrap() { - // Safe unwrap already checked if it contains an upstream withe `is_solo_miner` + // Safe unwrap already checked if it contains an upstream with `is_solo_miner` let upstream = self_mutex .safe_lock(|s| s.status.get_upstream().unwrap()) .unwrap(); diff --git a/roles/jd-client/src/lib/job_declarator/message_handler.rs b/roles/jd-client/src/lib/job_declarator/message_handler.rs index 7516f24f94..72d58a9126 100644 --- a/roles/jd-client/src/lib/job_declarator/message_handler.rs +++ b/roles/jd-client/src/lib/job_declarator/message_handler.rs @@ -55,12 +55,20 @@ impl ParseServerJobDeclarationMessages for JobDeclarator { ) -> Result { let tx_list = self .last_declare_mining_jobs_sent - .get(&message.request_id) - .unwrap() - .clone() - .unwrap() - .tx_list - .into_inner(); + .iter() + .find_map(|entry| { + if let Some((id, last_declare_job)) = entry { + if *id == message.request_id { + Some(last_declare_job.clone().tx_list.into_inner()) + } else { + None + } + } else { + None + } + }) + .ok_or_else(|| Error::UnknownRequestId(message.request_id))?; + let unknown_tx_position_list: Vec = message.unknown_tx_position_list.into_inner(); let missing_transactions: Vec = unknown_tx_position_list .iter() diff --git a/roles/jd-client/src/lib/job_declarator/mod.rs b/roles/jd-client/src/lib/job_declarator/mod.rs index abaf852ca2..5e5191cb1f 100644 --- a/roles/jd-client/src/lib/job_declarator/mod.rs +++ b/roles/jd-client/src/lib/job_declarator/mod.rs @@ -55,7 +55,7 @@ pub struct JobDeclarator { req_ids: Id, min_extranonce_size: u16, // (Sent DeclareMiningJob, is future, template id, merkle path) - last_declare_mining_jobs_sent: HashMap>, + last_declare_mining_jobs_sent: [Option<(u32, LastDeclareJob)>; 2], last_set_new_prev_hash: Option>, set_new_prev_hash_counter: u8, #[allow(clippy::type_complexity)] @@ -115,7 +115,7 @@ impl JobDeclarator { allocated_tokens: vec![], req_ids: Id::new(), min_extranonce_size, - last_declare_mining_jobs_sent: HashMap::with_capacity(10), + last_declare_mining_jobs_sent: [None, None], last_set_new_prev_hash: None, future_jobs: HashMap::with_hasher(BuildNoHashHasher::default()), up, @@ -130,14 +130,18 @@ impl JobDeclarator { Ok(self_) } - fn get_last_declare_job_sent(self_mutex: &Arc>, request_id: u32) -> LastDeclareJob { + fn get_last_declare_job_sent( + self_mutex: &Arc>, + request_id: u32, + ) -> Option { self_mutex .safe_lock(|s| { - s.last_declare_mining_jobs_sent - .get(&request_id) - .expect("LastDeclareJob not found") - .clone() - .expect("unreachable code") + for (id, job) in s.last_declare_mining_jobs_sent.iter().flatten() { + if *id == request_id { + return Some(job.to_owned()); + } + } + None }) .unwrap() } @@ -149,13 +153,20 @@ impl JobDeclarator { ) { self_mutex .safe_lock(|s| { - //check hashmap size in order to not let it grow indefinetely - if s.last_declare_mining_jobs_sent.len() < 10 { - s.last_declare_mining_jobs_sent.insert(request_id, Some(j)); - } else if let Some(min_key) = s.last_declare_mining_jobs_sent.keys().min().cloned() + if let Some(empty_index) = s + .last_declare_mining_jobs_sent + .iter() + .position(|entry| entry.is_none()) + { + s.last_declare_mining_jobs_sent[empty_index] = Some((request_id, j)); + } else if let Some((min_index, _)) = s + .last_declare_mining_jobs_sent + .iter() + .enumerate() + .filter_map(|(i, entry)| entry.as_ref().map(|(id, _)| (i, id))) + .min_by_key(|&(_, id)| id) { - s.last_declare_mining_jobs_sent.remove(&min_key); - s.last_declare_mining_jobs_sent.insert(request_id, Some(j)); + s.last_declare_mining_jobs_sent[min_index] = Some((request_id, j)); } }) .unwrap(); @@ -289,8 +300,7 @@ impl JobDeclarator { match next_message_to_send { Ok(SendTo::None(Some(JobDeclaration::DeclareMiningJobSuccess(m)))) => { let new_token = m.new_mining_job_token; - let last_declare = - Self::get_last_declare_job_sent(&self_mutex, m.request_id); + let last_declare = Self::get_last_declare_job_sent(&self_mutex, m.request_id).unwrap_or_else(|| panic!("Failed to get last declare job: job not found, Request Id: {:?}.", m.request_id)); let mut last_declare_mining_job_sent = last_declare.declare_job; let is_future = last_declare.template.future_template; let id = last_declare.template.template_id; diff --git a/roles/jd-client/src/lib/mod.rs b/roles/jd-client/src/lib/mod.rs index 489759420e..455e901cfd 100644 --- a/roles/jd-client/src/lib/mod.rs +++ b/roles/jd-client/src/lib/mod.rs @@ -15,7 +15,7 @@ use std::{sync::atomic::AtomicBool, time::Duration}; /// In the meantime if the context that is running the template receiver receives a SetNewPrevHash /// it wait until the value of this global is true before doing anything. /// -/// Acuire and Release memory ordering is used. +/// Acquire and Release memory ordering is used. /// /// Memory Ordering Explanation: /// We use Acquire-Release ordering instead of SeqCst or Relaxed for the following reasons: diff --git a/roles/jd-client/src/main.rs b/roles/jd-client/src/main.rs index c12a17b39c..27f05f361d 100644 --- a/roles/jd-client/src/main.rs +++ b/roles/jd-client/src/main.rs @@ -46,12 +46,12 @@ fn process_cli_args<'a>() -> ProxyResult<'a, ProxyConfig> { /// TODO on setupconnection with bitcoind (TP) JDC must signal that want a tx short hash list with /// the templates /// -/// TODO JDC must handle TxShortHahhList message +/// TODO JDC must handle TxShortHashList message /// /// This will start: /// 1. An Upstream, this will connect with the mining Pool /// 2. A listner that will wait for a mining downstream with ExtendedChannel capabilities (tproxy, -/// minin-proxy) +/// mining-proxy) /// 3. A JobDeclarator, this will connect with the job-declarator-server /// 4. A TemplateRx, this will connect with bitcoind /// @@ -78,15 +78,15 @@ fn process_cli_args<'a>() -> ProxyResult<'a, ProxyConfig> { /// Then we receive CommitMiningJobSuccess and we use the new token to send SetCustomMiningJob to /// the pool. /// When we receive SetCustomMiningJobSuccess we set in Upstream job_id equal to the one received -/// in SetCustomMiningJobSuccess so that we sill send shares upstream with the right job_id. +/// in SetCustomMiningJobSuccess so that we still send shares upstream with the right job_id. /// /// The above procedure, let us send NewExtendedMiningJob downstream right after a NewTemplate has /// been received this will reduce the time that pass from a NewTemplate and the mining-device /// starting to mine on the new job. /// /// In the case a future NewTemplate the SetCustomMiningJob is sent only if the canditate become -/// the actual NewTemplate so that we do not send a lot of usless future Job to the pool. That -/// means that SetCustomMiningJob is sent only when a NewTemplate becom "active" +/// the actual NewTemplate so that we do not send a lot of useless future Job to the pool. That +/// means that SetCustomMiningJob is sent only when a NewTemplate become "active" /// /// The JobDeclarator always have 2 avaiable token, that means that whenever a token is used to /// commit a job with upstream we require a new one. Having always a token when needed means that @@ -217,7 +217,7 @@ async fn initialize_jd_as_solo_miner( }; let miner_tx_out = lib::proxy_config::get_coinbase_output(&proxy_config).unwrap(); - // When Downstream receive a share that meets bitcoin target it transformit in a + // When Downstream receive a share that meets bitcoin target it transform it in a // SubmitSolution and send it to the TemplateReceiver let (send_solution, recv_solution) = bounded(10); @@ -290,7 +290,7 @@ async fn initialize_jd( port, ); - // When Downstream receive a share that meets bitcoin target it transformit in a + // When Downstream receive a share that meets bitcoin target it transform it in a // SubmitSolution and send it to the TemplateReceiver let (send_solution, recv_solution) = bounded(10); From c959f42b756111ae693ba93d88555dcaf5b1818c Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Tue, 2 Jul 2024 07:44:37 -0400 Subject: [PATCH 3/9] Add update last declare job sent method description snippet --- roles/jd-client/src/lib/job_declarator/mod.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/roles/jd-client/src/lib/job_declarator/mod.rs b/roles/jd-client/src/lib/job_declarator/mod.rs index 5e5191cb1f..9fad85cf76 100644 --- a/roles/jd-client/src/lib/job_declarator/mod.rs +++ b/roles/jd-client/src/lib/job_declarator/mod.rs @@ -146,6 +146,10 @@ impl JobDeclarator { .unwrap() } + /// We maintain a window of 2 jobs. If more than 2 blocks are found, + /// the ordering will depend on the request ID. Only the 2 most recent request + /// IDs will be kept in memory, while the rest will be discarded. + /// More information can be found here: https://github.com/stratum-mining/stratum/pull/904#discussion_r1609469048 fn update_last_declare_job_sent( self_mutex: &Arc>, request_id: u32, From e4112fb1132e094c5b1007f6c14b4776f1135b9d Mon Sep 17 00:00:00 2001 From: jbesraa Date: Tue, 18 Jun 2024 12:47:41 +0300 Subject: [PATCH 4/9] Refactor `header.rs` 1. Removed `NoiseHeader` struct in favor of three constants defined at the top of the file. 2. Added documentation and changed visibility to `pub(crate)` where needed. 3. Removed `Header::Default` and `Sv2Frame::Default` impls as they are unused. 4. Removed `unwrap()`s --- protocols/v2/codec-sv2/src/decoder.rs | 18 ++--- protocols/v2/codec-sv2/src/encoder.rs | 4 +- protocols/v2/framing-sv2/src/error.rs | 9 ++- protocols/v2/framing-sv2/src/framing2.rs | 24 ++---- protocols/v2/framing-sv2/src/header.rs | 96 +++++++++++++++--------- 5 files changed, 84 insertions(+), 67 deletions(-) diff --git a/protocols/v2/codec-sv2/src/decoder.rs b/protocols/v2/codec-sv2/src/decoder.rs index cba5843f2d..aebc0aee1d 100644 --- a/protocols/v2/codec-sv2/src/decoder.rs +++ b/protocols/v2/codec-sv2/src/decoder.rs @@ -10,7 +10,7 @@ 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}, header::Header, @@ -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()) } _ => { @@ -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) } _ => { @@ -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())) } diff --git a/protocols/v2/codec-sv2/src/encoder.rs b/protocols/v2/codec-sv2/src/encoder.rs index e4f544a198..a123422176 100644 --- a/protocols/v2/codec-sv2/src/encoder.rs +++ b/protocols/v2/codec-sv2/src/encoder.rs @@ -9,7 +9,7 @@ use core::marker::PhantomData; 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; @@ -76,7 +76,7 @@ impl NoiseEncoder { } 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); diff --git a/protocols/v2/framing-sv2/src/error.rs b/protocols/v2/framing-sv2/src/error.rs index 808b47d510..44b0c95cef 100644 --- a/protocols/v2/framing-sv2/src/error.rs +++ b/protocols/v2/framing-sv2/src/error.rs @@ -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 + ) } } } diff --git a/protocols/v2/framing-sv2/src/framing2.rs b/protocols/v2/framing-sv2/src/framing2.rs index 4ba8960633..692a22af4b 100644 --- a/protocols/v2/framing-sv2/src/framing2.rs +++ b/protocols/v2/framing-sv2/src/framing2.rs @@ -1,5 +1,5 @@ use crate::{ - header::{Header, NoiseHeader}, + header::{Header, NOISE_HEADER_LEN_OFFSET, NOISE_HEADER_SIZE}, Error, }; use alloc::vec::Vec; @@ -83,16 +83,6 @@ pub struct Sv2Frame { serialized: Option, } -impl Default for Sv2Frame { - 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 @@ -253,7 +243,7 @@ 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..] + &mut self.payload[NOISE_HEADER_SIZE..] } /// `HandShakeFrame` always returns `None`. @@ -280,17 +270,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 } } diff --git a/protocols/v2/framing-sv2/src/header.rs b/protocols/v2/framing-sv2/src/header.rs index 05272b52a7..3b32261560 100644 --- a/protocols/v2/framing-sv2/src/header.rs +++ b/protocols/v2/framing-sv2/src/header.rs @@ -7,68 +7,65 @@ use binary_sv2::{Deserialize, Serialize, U24}; use const_sv2::{AEAD_MAC_LEN, SV2_FRAME_CHUNK_SIZE}; use core::convert::TryInto; +// Previously `NoiseHeader::SIZE` +pub const NOISE_HEADER_ENCRYPTED_SIZE: usize = const_sv2::ENCRYPTED_SV2_FRAME_HEADER_SIZE; +// Previously `NoiseHeader::LEN_OFFSET` +pub const NOISE_HEADER_LEN_OFFSET: usize = const_sv2::NOISE_FRAME_HEADER_LEN_OFFSET; +// Previously `NoiseHeader::HEADER_SIZE` +pub const NOISE_HEADER_SIZE: usize = const_sv2::NOISE_FRAME_HEADER_SIZE; + /// Abstraction for a SV2 Frame Header. #[derive(Debug, Serialize, Deserialize, Copy, Clone)] pub struct Header { - extension_type: u16, // TODO use specific type? - msg_type: u8, // TODO use specific type? + /// Unique identifier of the extension describing this protocol message. Most significant bit + /// (i.e.bit 15, 0-indexed, aka channel_msg) indicates a message which is specific to a channel, + /// whereas if the most significant bit is unset, the message is to be interpreted by the + /// immediate receiving device. Note that the channel_msg bit is ignored in the extension + /// lookup, i.e.an extension_type of 0x8ABC is for the same "extension" as 0x0ABC. If the + /// channel_msg bit is set, the first four bytes of the payload field is a U32 representing the + /// channel_id this message is destined for. Note that for the Job Declaration and Template + /// Distribution Protocols the channel_msg bit is always unset. + extension_type: u16, // fix: use U16 type + /// Unique identifier of the extension describing this protocol message + msg_type: u8, // fix: use specific type? + /// Length of the protocol message, not including this header msg_length: U24, } -impl Default for Header { - fn default() -> Self { - Header { - extension_type: 0, - msg_type: 0, - // converting 0_32 into a U24 never panic - msg_length: 0_u32.try_into().unwrap(), - } - } -} - impl Header { - pub const LEN_OFFSET: usize = const_sv2::SV2_FRAME_HEADER_LEN_OFFSET; - pub const LEN_SIZE: usize = const_sv2::SV2_FRAME_HEADER_LEN_END; - pub const LEN_END: usize = Self::LEN_OFFSET + Self::LEN_SIZE; - pub const SIZE: usize = const_sv2::SV2_FRAME_HEADER_SIZE; - /// Construct a `Header` from ray bytes + /// Construct a `Header` from raw bytes #[inline] pub fn from_bytes(bytes: &[u8]) -> Result { if bytes.len() < Self::SIZE { - return Err(Error::UnexpectedHeaderLength( - (Self::SIZE - bytes.len()) as isize, - )); + return Err(Error::UnexpectedHeaderLength(bytes.len() as isize)); }; - let extension_type = u16::from_le_bytes([bytes[0], bytes[1]]); let msg_type = bytes[2]; - let msg_length = u32::from_le_bytes([bytes[3], bytes[4], bytes[5], 0]); - + let msg_length: U24 = u32::from_le_bytes([bytes[3], bytes[4], bytes[5], 0]).try_into()?; Ok(Self { extension_type, msg_type, - // Converting and u32 with the most significant byte set to 0 to and U24 never panic - msg_length: msg_length.try_into().unwrap(), + msg_length, }) } /// Get the payload length #[allow(clippy::len_without_is_empty)] #[inline] - pub fn len(&self) -> usize { + pub(crate) fn len(&self) -> usize { let inner: u32 = self.msg_length.into(); inner as usize } /// Construct a `Header` from payload length, type and extension type. #[inline] - pub fn from_len(len: u32, message_type: u8, extension_type: u16) -> Option
{ + pub(crate) fn from_len(msg_length: u32, msg_type: u8, extension_type: u16) -> Option
{ Some(Self { extension_type, - msg_type: message_type, - msg_length: len.try_into().ok()?, + msg_type, + msg_length: msg_length.try_into().ok()?, }) } @@ -83,9 +80,11 @@ impl Header { } /// Check if `Header` represents a channel message + /// + /// A header can represent a channel message if the MSB(Most Significant Bit) is set. pub fn channel_msg(&self) -> bool { - let mask = 0b0000_0000_0000_0001; - self.extension_type & mask == self.extension_type + const CHANNEL_MSG_MASK: u16 = 0b0000_0000_0000_0001; + self.extension_type & CHANNEL_MSG_MASK == self.extension_type } /// Calculate the length of the encrypted `Header` @@ -100,10 +99,33 @@ impl Header { } } -pub struct NoiseHeader {} +#[cfg(test)] +mod tests { + use super::*; + use alloc::vec; + + #[test] + fn test_header_from_bytes() { + let bytes = vec![0x01, 0x02, 0x03, 0x04, 0x05, 0x06]; + let header = Header::from_bytes(&bytes).unwrap(); + assert_eq!(header.extension_type, 0x0201); + assert_eq!(header.msg_type, 0x03); + assert_eq!(header.msg_length, 0x060504_u32.try_into().unwrap()); + } + + #[test] + fn test_header_from_len() { + let header = Header::from_len(0x1234, 0x56, 0x789a).unwrap(); + assert_eq!(header.extension_type, 0x789a); + assert_eq!(header.msg_type, 0x56); + assert_eq!(header.msg_length, 0x1234_u32.try_into().unwrap()); -impl NoiseHeader { - pub const SIZE: usize = const_sv2::ENCRYPTED_SV2_FRAME_HEADER_SIZE; - pub const LEN_OFFSET: usize = const_sv2::NOISE_FRAME_HEADER_LEN_OFFSET; - pub const HEADER_SIZE: usize = const_sv2::NOISE_FRAME_HEADER_SIZE; + let extension_type = 0; + let msg_type = 0x1; + let msg_length = 0x1234_u32; + let header = Header::from_len(msg_length, msg_type, extension_type).unwrap(); + assert_eq!(header.extension_type, 0); + assert_eq!(header.msg_type, 0x1); + assert_eq!(header.msg_length, 0x1234_u32.try_into().unwrap()); + } } From f0b672e5724f354c95609c1eaa073b87fff0e21d Mon Sep 17 00:00:00 2001 From: jbesraa Date: Tue, 18 Jun 2024 15:17:26 +0300 Subject: [PATCH 5/9] Remove `Frame` trait The `Frame` trait is used solely by a single struct and it is only adding biolerplate to the code without benifits. We could consider re-adding it in the future if needed. --- .../src/sv2/criterion_sv2_benchmark.rs | 2 +- benches/benches/src/sv2/iai_sv2_benchmark.rs | 2 +- examples/interop-cpp/src/main.rs | 2 +- examples/ping-pong-with-noise/src/node.rs | 2 +- examples/ping-pong-without-noise/src/node.rs | 2 +- examples/template-provider-test/src/main.rs | 2 +- protocols/fuzz-tests/src/main.rs | 2 +- protocols/v2/codec-sv2/src/decoder.rs | 2 +- protocols/v2/codec-sv2/src/encoder.rs | 2 +- protocols/v2/codec-sv2/src/lib.rs | 2 +- protocols/v2/framing-sv2/src/framing2.rs | 78 ++++--------------- protocols/v2/roles-logic-sv2/src/parsers.rs | 2 +- protocols/v2/sv2-ffi/src/lib.rs | 2 +- roles/jd-client/src/lib/downstream.rs | 2 +- roles/jd-client/src/lib/job_declarator/mod.rs | 1 - .../lib/job_declarator/setup_connection.rs | 2 +- .../src/lib/template_receiver/mod.rs | 2 +- .../lib/template_receiver/setup_connection.rs | 2 +- .../src/lib/upstream_sv2/upstream.rs | 2 +- roles/jd-server/src/lib/job_declarator/mod.rs | 2 +- .../mining-proxy/src/lib/downstream_mining.rs | 2 +- roles/mining-proxy/src/lib/upstream_mining.rs | 2 +- roles/pool/src/lib/mining_pool/mod.rs | 2 +- .../src/lib/mining_pool/setup_connection.rs | 1 - roles/pool/src/lib/template_receiver/mod.rs | 2 +- .../lib/template_receiver/setup_connection.rs | 1 - roles/test-utils/mining-device/src/main.rs | 2 +- .../src/lib/upstream_sv2/upstream.rs | 2 +- utils/message-generator/src/executor.rs | 2 +- utils/message-generator/src/main.rs | 2 +- utils/message-generator/src/parser/frames.rs | 2 +- 31 files changed, 41 insertions(+), 94 deletions(-) diff --git a/benches/benches/src/sv2/criterion_sv2_benchmark.rs b/benches/benches/src/sv2/criterion_sv2_benchmark.rs index 7aa35f158c..18fab853d9 100644 --- a/benches/benches/src/sv2/criterion_sv2_benchmark.rs +++ b/benches/benches/src/sv2/criterion_sv2_benchmark.rs @@ -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}, diff --git a/benches/benches/src/sv2/iai_sv2_benchmark.rs b/benches/benches/src/sv2/iai_sv2_benchmark.rs index 2cab39cc47..b049b9dc42 100644 --- a/benches/benches/src/sv2/iai_sv2_benchmark.rs +++ b/benches/benches/src/sv2/iai_sv2_benchmark.rs @@ -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_}, diff --git a/examples/interop-cpp/src/main.rs b/examples/interop-cpp/src/main.rs index 34f6bef09c..09950e94b0 100644 --- a/examples/interop-cpp/src/main.rs +++ b/examples/interop-cpp/src/main.rs @@ -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, diff --git a/examples/ping-pong-with-noise/src/node.rs b/examples/ping-pong-with-noise/src/node.rs index 912d6e8357..1ae042aa83 100644 --- a/examples/ping-pong-with-noise/src/node.rs +++ b/examples/ping-pong-with-noise/src/node.rs @@ -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; diff --git a/examples/ping-pong-without-noise/src/node.rs b/examples/ping-pong-without-noise/src/node.rs index 97295d591f..21edf617e1 100644 --- a/examples/ping-pong-without-noise/src/node.rs +++ b/examples/ping-pong-without-noise/src/node.rs @@ -10,7 +10,7 @@ use async_std::{ task, }; -use codec_sv2::{Frame, StandardDecoder, StandardSv2Frame}; +use codec_sv2::{StandardDecoder, StandardSv2Frame}; #[derive(Debug)] enum Expected { diff --git a/examples/template-provider-test/src/main.rs b/examples/template-provider-test/src/main.rs index 78878227b5..5a83aa39a7 100644 --- a/examples/template-provider-test/src/main.rs +++ b/examples/template-provider-test/src/main.rs @@ -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}, diff --git a/protocols/fuzz-tests/src/main.rs b/protocols/fuzz-tests/src/main.rs index c9623ecb51..bb2364c0fd 100644 --- a/protocols/fuzz-tests/src/main.rs +++ b/protocols/fuzz-tests/src/main.rs @@ -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,Vec>; diff --git a/protocols/v2/codec-sv2/src/decoder.rs b/protocols/v2/codec-sv2/src/decoder.rs index aebc0aee1d..4a946a1e14 100644 --- a/protocols/v2/codec-sv2/src/decoder.rs +++ b/protocols/v2/codec-sv2/src/decoder.rs @@ -12,7 +12,7 @@ use framing_sv2::framing2::HandShakeFrame; #[cfg(feature = "noise_sv2")] 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")] diff --git a/protocols/v2/codec-sv2/src/encoder.rs b/protocols/v2/codec-sv2/src/encoder.rs index a123422176..9ecc37c3e1 100644 --- a/protocols/v2/codec-sv2/src/encoder.rs +++ b/protocols/v2/codec-sv2/src/encoder.rs @@ -5,9 +5,9 @@ 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::NOISE_HEADER_ENCRYPTED_SIZE; diff --git a/protocols/v2/codec-sv2/src/lib.rs b/protocols/v2/codec-sv2/src/lib.rs index f5cbc013d2..184c39fda8 100644 --- a/protocols/v2/codec-sv2/src/lib.rs +++ b/protocols/v2/codec-sv2/src/lib.rs @@ -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}; diff --git a/protocols/v2/framing-sv2/src/framing2.rs b/protocols/v2/framing-sv2/src/framing2.rs index 692a22af4b..eec461fa9f 100644 --- a/protocols/v2/framing-sv2/src/framing2.rs +++ b/protocols/v2/framing-sv2/src/framing2.rs @@ -1,3 +1,4 @@ +#![allow(dead_code)] use crate::{ header::{Header, NOISE_HEADER_LEN_OFFSET, NOISE_HEADER_SIZE}, Error, @@ -29,51 +30,6 @@ impl Sv2Frame { } } -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; - - /// 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; - - /// 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; -} - /// Abstraction for a SV2 Frame. #[derive(Debug, Clone)] pub struct Sv2Frame { @@ -98,15 +54,12 @@ impl HandShakeFrame { } } -impl<'a, T: Serialize + GetSize, B: AsMut<[u8]> + AsRef<[u8]>> Frame<'a, T> for Sv2Frame { - type Buffer = B; - type Deserialized = B; - +impl + AsRef<[u8]>> Sv2Frame { /// 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(()) @@ -132,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 { @@ -142,7 +95,7 @@ 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 { + pub fn get_header(&self) -> Option { Some(self.header) } @@ -150,7 +103,7 @@ impl<'a, T: Serialize + GetSize, B: AsMut<[u8]> + AsRef<[u8]>> Frame<'a, T> for /// 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 { + pub fn from_bytes(mut bytes: B) -> Result { let hint = Self::size_hint(bytes.as_mut()); if hint == 0 { @@ -161,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 { @@ -179,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 @@ -200,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() { @@ -213,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, @@ -229,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> { @@ -242,7 +192,7 @@ impl<'a> Frame<'a, Slice> for HandShakeFrame { /// Get the Noise Frame payload #[inline] - fn payload(&'a mut self) -> &'a mut [u8] { + fn payload(&mut self) -> &mut [u8] { &mut self.payload[NOISE_HEADER_SIZE..] } @@ -252,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 { + pub fn from_bytes(bytes: Slice) -> Result { 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 } } diff --git a/protocols/v2/roles-logic-sv2/src/parsers.rs b/protocols/v2/roles-logic-sv2/src/parsers.rs index 6eaf5e016c..4d80387c91 100644 --- a/protocols/v2/roles-logic-sv2/src/parsers.rs +++ b/protocols/v2/roles-logic-sv2/src/parsers.rs @@ -13,7 +13,7 @@ use binary_sv2::GetSize; use binary_sv2::{from_bytes, Deserialize}; -use framing_sv2::framing2::{Frame, Sv2Frame}; +use framing_sv2::framing2::Sv2Frame; use const_sv2::{ CHANNEL_BIT_ALLOCATE_MINING_JOB_TOKEN, CHANNEL_BIT_ALLOCATE_MINING_JOB_TOKEN_SUCCESS, diff --git a/protocols/v2/sv2-ffi/src/lib.rs b/protocols/v2/sv2-ffi/src/lib.rs index 346d497b91..9befa0ca73 100644 --- a/protocols/v2/sv2-ffi/src/lib.rs +++ b/protocols/v2/sv2-ffi/src/lib.rs @@ -4,7 +4,7 @@ use std::{ fmt::{Display, Formatter}, }; -use codec_sv2::{Encoder, Frame, StandardDecoder, StandardSv2Frame}; +use codec_sv2::{Encoder, StandardDecoder, StandardSv2Frame}; use common_messages_sv2::{ CSetupConnection, CSetupConnectionError, ChannelEndpointChanged, SetupConnection, SetupConnectionError, SetupConnectionSuccess, diff --git a/roles/jd-client/src/lib/downstream.rs b/roles/jd-client/src/lib/downstream.rs index da14c7b0aa..5b26cef2f7 100644 --- a/roles/jd-client/src/lib/downstream.rs +++ b/roles/jd-client/src/lib/downstream.rs @@ -21,7 +21,7 @@ use roles_logic_sv2::{ }; use tracing::{debug, error, info, warn}; -use codec_sv2::{Frame, HandshakeRole, Responder, StandardEitherFrame, StandardSv2Frame}; +use codec_sv2::{HandshakeRole, Responder, StandardEitherFrame, StandardSv2Frame}; use key_utils::{Secp256k1PublicKey, Secp256k1SecretKey}; use stratum_common::bitcoin::{consensus::Decodable, TxOut}; diff --git a/roles/jd-client/src/lib/job_declarator/mod.rs b/roles/jd-client/src/lib/job_declarator/mod.rs index 9fad85cf76..29fb2e4f2c 100644 --- a/roles/jd-client/src/lib/job_declarator/mod.rs +++ b/roles/jd-client/src/lib/job_declarator/mod.rs @@ -17,7 +17,6 @@ use tokio::task::AbortHandle; use tracing::{error, info}; use async_recursion::async_recursion; -use codec_sv2::Frame; use nohash_hasher::BuildNoHashHasher; use roles_logic_sv2::{ handlers::job_declaration::ParseServerJobDeclarationMessages, diff --git a/roles/jd-client/src/lib/job_declarator/setup_connection.rs b/roles/jd-client/src/lib/job_declarator/setup_connection.rs index 063592c403..0e7b6fd8aa 100644 --- a/roles/jd-client/src/lib/job_declarator/setup_connection.rs +++ b/roles/jd-client/src/lib/job_declarator/setup_connection.rs @@ -1,5 +1,5 @@ use async_channel::{Receiver, Sender}; -use codec_sv2::{Frame, StandardEitherFrame, StandardSv2Frame}; +use codec_sv2::{StandardEitherFrame, StandardSv2Frame}; use roles_logic_sv2::{ common_messages_sv2::{Protocol, SetupConnection}, handlers::common::{ParseUpstreamCommonMessages, SendTo}, diff --git a/roles/jd-client/src/lib/template_receiver/mod.rs b/roles/jd-client/src/lib/template_receiver/mod.rs index 02d3d04972..f418318a88 100644 --- a/roles/jd-client/src/lib/template_receiver/mod.rs +++ b/roles/jd-client/src/lib/template_receiver/mod.rs @@ -1,6 +1,6 @@ use super::{job_declarator::JobDeclarator, status, PoolChangerTrigger}; use async_channel::{Receiver, Sender}; -use codec_sv2::{Frame, HandshakeRole, Initiator, StandardEitherFrame, StandardSv2Frame}; +use codec_sv2::{HandshakeRole, Initiator, StandardEitherFrame, StandardSv2Frame}; use error_handling::handle_result; use key_utils::Secp256k1PublicKey; use network_helpers_sv2::noise_connection_tokio::Connection; diff --git a/roles/jd-client/src/lib/template_receiver/setup_connection.rs b/roles/jd-client/src/lib/template_receiver/setup_connection.rs index 45f48a2f44..505b945c3e 100644 --- a/roles/jd-client/src/lib/template_receiver/setup_connection.rs +++ b/roles/jd-client/src/lib/template_receiver/setup_connection.rs @@ -1,5 +1,5 @@ use async_channel::{Receiver, Sender}; -use codec_sv2::{Frame, StandardEitherFrame, StandardSv2Frame}; +use codec_sv2::{StandardEitherFrame, StandardSv2Frame}; use roles_logic_sv2::{ common_messages_sv2::{Protocol, SetupConnection}, handlers::common::{ParseUpstreamCommonMessages, SendTo}, diff --git a/roles/jd-client/src/lib/upstream_sv2/upstream.rs b/roles/jd-client/src/lib/upstream_sv2/upstream.rs index 857cbd3087..b04efa3359 100644 --- a/roles/jd-client/src/lib/upstream_sv2/upstream.rs +++ b/roles/jd-client/src/lib/upstream_sv2/upstream.rs @@ -11,7 +11,7 @@ use super::super::{ }; use async_channel::{Receiver, Sender}; use binary_sv2::{Seq0255, U256}; -use codec_sv2::{Frame, HandshakeRole, Initiator}; +use codec_sv2::{HandshakeRole, Initiator}; use error_handling::handle_result; use key_utils::Secp256k1PublicKey; use network_helpers_sv2::noise_connection_tokio::Connection; diff --git a/roles/jd-server/src/lib/job_declarator/mod.rs b/roles/jd-server/src/lib/job_declarator/mod.rs index 56d56223cc..34d9e66de4 100644 --- a/roles/jd-server/src/lib/job_declarator/mod.rs +++ b/roles/jd-server/src/lib/job_declarator/mod.rs @@ -2,7 +2,7 @@ pub mod message_handler; use super::{error::JdsError, mempool::JDsMempool, status, Configuration, EitherFrame, StdFrame}; use async_channel::{Receiver, Sender}; use binary_sv2::{B0255, U256}; -use codec_sv2::{Frame, HandshakeRole, Responder}; +use codec_sv2::{HandshakeRole, Responder}; use error_handling::handle_result; use key_utils::{Secp256k1PublicKey, Secp256k1SecretKey, SignatureService}; use network_helpers_sv2::noise_connection_tokio::Connection; diff --git a/roles/mining-proxy/src/lib/downstream_mining.rs b/roles/mining-proxy/src/lib/downstream_mining.rs index d4e9bcb174..1880551196 100644 --- a/roles/mining-proxy/src/lib/downstream_mining.rs +++ b/roles/mining-proxy/src/lib/downstream_mining.rs @@ -17,7 +17,7 @@ use roles_logic_sv2::{ }; use tracing::info; -use codec_sv2::{Frame, StandardEitherFrame, StandardSv2Frame}; +use codec_sv2::{StandardEitherFrame, StandardSv2Frame}; pub type Message = MiningDeviceMessages<'static>; pub type StdFrame = StandardSv2Frame; diff --git a/roles/mining-proxy/src/lib/upstream_mining.rs b/roles/mining-proxy/src/lib/upstream_mining.rs index 61a5d0f31a..e3f6eef999 100644 --- a/roles/mining-proxy/src/lib/upstream_mining.rs +++ b/roles/mining-proxy/src/lib/upstream_mining.rs @@ -6,7 +6,7 @@ use roles_logic_sv2::utils::Id; use super::downstream_mining::{Channel, DownstreamMiningNode, StdFrame as DownstreamFrame}; use async_channel::{Receiver, SendError, Sender}; use async_recursion::async_recursion; -use codec_sv2::{Frame, HandshakeRole, Initiator, StandardEitherFrame, StandardSv2Frame}; +use codec_sv2::{HandshakeRole, Initiator, StandardEitherFrame, StandardSv2Frame}; use network_helpers_sv2::noise_connection_tokio::Connection; use nohash_hasher::BuildNoHashHasher; use roles_logic_sv2::{ diff --git a/roles/pool/src/lib/mining_pool/mod.rs b/roles/pool/src/lib/mining_pool/mod.rs index e189c5406a..4b9d10b188 100644 --- a/roles/pool/src/lib/mining_pool/mod.rs +++ b/roles/pool/src/lib/mining_pool/mod.rs @@ -4,7 +4,7 @@ use super::{ }; use async_channel::{Receiver, Sender}; use binary_sv2::U256; -use codec_sv2::{Frame, HandshakeRole, Responder, StandardEitherFrame, StandardSv2Frame}; +use codec_sv2::{HandshakeRole, Responder, StandardEitherFrame, StandardSv2Frame}; use error_handling::handle_result; use key_utils::{Secp256k1PublicKey, Secp256k1SecretKey, SignatureService}; use network_helpers_sv2::noise_connection_tokio::Connection; diff --git a/roles/pool/src/lib/mining_pool/setup_connection.rs b/roles/pool/src/lib/mining_pool/setup_connection.rs index cf2c06022d..f0c47e9a88 100644 --- a/roles/pool/src/lib/mining_pool/setup_connection.rs +++ b/roles/pool/src/lib/mining_pool/setup_connection.rs @@ -3,7 +3,6 @@ use super::super::{ mining_pool::{EitherFrame, StdFrame}, }; use async_channel::{Receiver, Sender}; -use codec_sv2::Frame; use roles_logic_sv2::{ common_messages_sv2::{ has_requires_std_job, has_version_rolling, has_work_selection, SetupConnection, diff --git a/roles/pool/src/lib/template_receiver/mod.rs b/roles/pool/src/lib/template_receiver/mod.rs index 49d58e82a8..2eeaa554f8 100644 --- a/roles/pool/src/lib/template_receiver/mod.rs +++ b/roles/pool/src/lib/template_receiver/mod.rs @@ -4,7 +4,7 @@ use super::{ status, }; use async_channel::{Receiver, Sender}; -use codec_sv2::{Frame, HandshakeRole, Initiator}; +use codec_sv2::{HandshakeRole, Initiator}; use error_handling::handle_result; use key_utils::Secp256k1PublicKey; use network_helpers_sv2::noise_connection_tokio::Connection; diff --git a/roles/pool/src/lib/template_receiver/setup_connection.rs b/roles/pool/src/lib/template_receiver/setup_connection.rs index 60c3cb4f84..6687eadc67 100644 --- a/roles/pool/src/lib/template_receiver/setup_connection.rs +++ b/roles/pool/src/lib/template_receiver/setup_connection.rs @@ -3,7 +3,6 @@ use super::super::{ mining_pool::{EitherFrame, StdFrame}, }; use async_channel::{Receiver, Sender}; -use codec_sv2::Frame; use roles_logic_sv2::{ common_messages_sv2::{Protocol, SetupConnection}, errors::Error, diff --git a/roles/test-utils/mining-device/src/main.rs b/roles/test-utils/mining-device/src/main.rs index 1bfbf6737a..763f83af5a 100644 --- a/roles/test-utils/mining-device/src/main.rs +++ b/roles/test-utils/mining-device/src/main.rs @@ -110,7 +110,7 @@ async fn main() { use async_channel::{Receiver, Sender}; use binary_sv2::u256_from_int; -use codec_sv2::{Frame, Initiator, StandardEitherFrame, StandardSv2Frame}; +use codec_sv2::{Initiator, StandardEitherFrame, StandardSv2Frame}; use roles_logic_sv2::{ common_messages_sv2::{Protocol, SetupConnection, SetupConnectionSuccess}, common_properties::{IsMiningUpstream, IsUpstream}, diff --git a/roles/translator/src/lib/upstream_sv2/upstream.rs b/roles/translator/src/lib/upstream_sv2/upstream.rs index f6d192f75e..6aab5978e4 100644 --- a/roles/translator/src/lib/upstream_sv2/upstream.rs +++ b/roles/translator/src/lib/upstream_sv2/upstream.rs @@ -11,7 +11,7 @@ use crate::{ use async_channel::{Receiver, Sender}; use async_std::{net::TcpStream, task}; use binary_sv2::u256_from_int; -use codec_sv2::{Frame, HandshakeRole, Initiator}; +use codec_sv2::{HandshakeRole, Initiator}; use error_handling::handle_result; use key_utils::Secp256k1PublicKey; use network_helpers_sv2::Connection; diff --git a/utils/message-generator/src/executor.rs b/utils/message-generator/src/executor.rs index b69bce0e6b..f31991eca2 100644 --- a/utils/message-generator/src/executor.rs +++ b/utils/message-generator/src/executor.rs @@ -7,7 +7,7 @@ use crate::{ }; use async_channel::{Receiver, Sender}; use binary_sv2::Serialize; -use codec_sv2::{Frame, StandardEitherFrame as EitherFrame, Sv2Frame}; +use codec_sv2::{StandardEitherFrame as EitherFrame, Sv2Frame}; use roles_logic_sv2::parsers::{self, AnyMessage}; use std::{collections::HashMap, convert::TryInto, sync::Arc}; diff --git a/utils/message-generator/src/main.rs b/utils/message-generator/src/main.rs index 695b3919cd..e2633ed23a 100644 --- a/utils/message-generator/src/main.rs +++ b/utils/message-generator/src/main.rs @@ -451,7 +451,7 @@ mod test { into_static::into_static, net::{setup_as_downstream, setup_as_upstream}, }; - use codec_sv2::{Frame, Sv2Frame}; + use codec_sv2::Sv2Frame; use roles_logic_sv2::{ mining_sv2::{ CloseChannel, NewExtendedMiningJob, OpenExtendedMiningChannel, diff --git a/utils/message-generator/src/parser/frames.rs b/utils/message-generator/src/parser/frames.rs index 633163200b..cd4c2c5823 100644 --- a/utils/message-generator/src/parser/frames.rs +++ b/utils/message-generator/src/parser/frames.rs @@ -1,5 +1,5 @@ use super::sv2_messages::{message_from_path, ReplaceField}; -use codec_sv2::{buffer_sv2::Slice, Frame as _Frame, Sv2Frame}; +use codec_sv2::{buffer_sv2::Slice, Sv2Frame}; use roles_logic_sv2::parsers::AnyMessage; use serde_json::{Map, Value}; use std::{collections::HashMap, convert::TryInto}; From 7c0e456a256c56e264a472688cdd8ed4f30fa4f3 Mon Sep 17 00:00:00 2001 From: jbesraa Date: Wed, 19 Jun 2024 10:52:29 +0300 Subject: [PATCH 6/9] Rename `framing2.rs` to `framing.rs` --- protocols/v2/codec-sv2/src/decoder.rs | 4 ++-- protocols/v2/codec-sv2/src/encoder.rs | 4 ++-- protocols/v2/codec-sv2/src/lib.rs | 6 +++--- protocols/v2/framing-sv2/src/{framing2.rs => framing.rs} | 0 protocols/v2/framing-sv2/src/lib.rs | 2 +- protocols/v2/roles-logic-sv2/src/parsers.rs | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) rename protocols/v2/framing-sv2/src/{framing2.rs => framing.rs} (100%) diff --git a/protocols/v2/codec-sv2/src/decoder.rs b/protocols/v2/codec-sv2/src/decoder.rs index 4a946a1e14..9f5f8e89ac 100644 --- a/protocols/v2/codec-sv2/src/decoder.rs +++ b/protocols/v2/codec-sv2/src/decoder.rs @@ -8,11 +8,11 @@ pub use buffer_sv2::AeadBuffer; pub use const_sv2::{SV2_FRAME_CHUNK_SIZE, SV2_FRAME_HEADER_SIZE}; use core::marker::PhantomData; #[cfg(feature = "noise_sv2")] -use framing_sv2::framing2::HandShakeFrame; +use framing_sv2::framing::HandShakeFrame; #[cfg(feature = "noise_sv2")] use framing_sv2::header::{NOISE_HEADER_ENCRYPTED_SIZE, NOISE_HEADER_SIZE}; use framing_sv2::{ - framing2::{EitherFrame, Sv2Frame}, + framing::{EitherFrame, Sv2Frame}, header::Header, }; #[cfg(feature = "noise_sv2")] diff --git a/protocols/v2/codec-sv2/src/encoder.rs b/protocols/v2/codec-sv2/src/encoder.rs index 9ecc37c3e1..39d10f00bf 100644 --- a/protocols/v2/codec-sv2/src/encoder.rs +++ b/protocols/v2/codec-sv2/src/encoder.rs @@ -5,9 +5,9 @@ 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; +use framing_sv2::framing::Sv2Frame; #[cfg(feature = "noise_sv2")] -use framing_sv2::framing2::{EitherFrame, HandShakeFrame}; +use framing_sv2::framing::{EitherFrame, HandShakeFrame}; #[allow(unused_imports)] pub use framing_sv2::header::NOISE_HEADER_ENCRYPTED_SIZE; diff --git a/protocols/v2/codec-sv2/src/lib.rs b/protocols/v2/codec-sv2/src/lib.rs index 184c39fda8..0a2492890f 100644 --- a/protocols/v2/codec-sv2/src/lib.rs +++ b/protocols/v2/codec-sv2/src/lib.rs @@ -22,15 +22,15 @@ pub use encoder::Encoder; pub use encoder::NoiseEncoder; #[cfg(feature = "noise_sv2")] -pub use framing_sv2::framing2::HandShakeFrame; -pub use framing_sv2::framing2::Sv2Frame; +pub use framing_sv2::framing::HandShakeFrame; +pub use framing_sv2::framing::Sv2Frame; #[cfg(feature = "noise_sv2")] pub use noise_sv2::{self, Initiator, NoiseCodec, Responder}; pub use buffer_sv2; -pub use framing_sv2::{self, framing2::handshake_message_to_frame as h2f}; +pub use framing_sv2::{self, framing::handshake_message_to_frame as h2f}; #[cfg(feature = "noise_sv2")] #[derive(Debug)] diff --git a/protocols/v2/framing-sv2/src/framing2.rs b/protocols/v2/framing-sv2/src/framing.rs similarity index 100% rename from protocols/v2/framing-sv2/src/framing2.rs rename to protocols/v2/framing-sv2/src/framing.rs diff --git a/protocols/v2/framing-sv2/src/lib.rs b/protocols/v2/framing-sv2/src/lib.rs index 34fe8708b6..33dd11fe2f 100644 --- a/protocols/v2/framing-sv2/src/lib.rs +++ b/protocols/v2/framing-sv2/src/lib.rs @@ -23,7 +23,7 @@ extern crate alloc; /// SV2 framing types -pub mod framing2; +pub mod framing; /// SV2 framing errors pub mod error; diff --git a/protocols/v2/roles-logic-sv2/src/parsers.rs b/protocols/v2/roles-logic-sv2/src/parsers.rs index 4d80387c91..0274ce785c 100644 --- a/protocols/v2/roles-logic-sv2/src/parsers.rs +++ b/protocols/v2/roles-logic-sv2/src/parsers.rs @@ -13,7 +13,7 @@ use binary_sv2::GetSize; use binary_sv2::{from_bytes, Deserialize}; -use framing_sv2::framing2::Sv2Frame; +use framing_sv2::framing::Sv2Frame; use const_sv2::{ CHANNEL_BIT_ALLOCATE_MINING_JOB_TOKEN, CHANNEL_BIT_ALLOCATE_MINING_JOB_TOKEN_SUCCESS, From 813fcfd8a3b2019cb3d311b6792813501e58be13 Mon Sep 17 00:00:00 2001 From: jbesraa Date: Wed, 19 Jun 2024 12:13:13 +0300 Subject: [PATCH 7/9] Reorder `framing.rs` so `structs` are ..followed by their `impl` - Also removed double `impl HandShakeFram {}` occurance --- protocols/v2/framing-sv2/src/framing.rs | 154 ++++++++++++------------ 1 file changed, 77 insertions(+), 77 deletions(-) diff --git a/protocols/v2/framing-sv2/src/framing.rs b/protocols/v2/framing-sv2/src/framing.rs index eec461fa9f..23f3c18d06 100644 --- a/protocols/v2/framing-sv2/src/framing.rs +++ b/protocols/v2/framing-sv2/src/framing.rs @@ -15,21 +15,35 @@ type Slice = Vec; #[cfg(feature = "with_buffer_pool")] type Slice = buffer_sv2::Slice; -impl Sv2Frame { - /// Maps a `Sv2Frame` to `Sv2Frame` by applying `fun`, - /// which is assumed to be a closure that converts `A` to `C` - pub fn map(self, fun: fn(A) -> C) -> Sv2Frame { - let serialized = self.serialized; - let header = self.header; - let payload = self.payload.map(fun); - Sv2Frame { - header, - payload, - serialized, +/// A wrapper to be used in a context we need a generic reference to a frame +/// but it doesn't matter which kind of frame it is (`Sv2Frame` or `HandShakeFrame`) +#[derive(Debug)] +pub enum EitherFrame { + HandShake(HandShakeFrame), + Sv2(Sv2Frame), +} + +impl + AsRef<[u8]>> EitherFrame { + pub fn encoded_length(&self) -> usize { + match &self { + Self::HandShake(frame) => frame.encoded_length(), + Self::Sv2(frame) => frame.encoded_length(), } } } +impl From for EitherFrame { + fn from(v: HandShakeFrame) -> Self { + Self::HandShake(v) + } +} + +impl From> for EitherFrame { + fn from(v: Sv2Frame) -> Self { + Self::Sv2(v) + } +} + /// Abstraction for a SV2 Frame. #[derive(Debug, Clone)] pub struct Sv2Frame { @@ -39,21 +53,6 @@ pub struct Sv2Frame { serialized: Option, } -/// Abstraction for a Noise Handshake Frame -/// Contains only a `Slice` payload with a fixed length -/// Only used during Noise Handshake process -#[derive(Debug)] -pub struct HandShakeFrame { - payload: Slice, -} - -impl HandShakeFrame { - /// Returns payload of `HandShakeFrame` as a `Vec` - pub fn get_payload_when_handshaking(&self) -> Vec { - self.payload[0..].to_vec() - } -} - impl + AsRef<[u8]>> Sv2Frame { /// Write the serialized `Sv2Frame` into `dst`. /// This operation when called on an already serialized frame is very cheap. @@ -182,6 +181,41 @@ impl + AsRef<[u8]>> Sv2Frame { } } +impl Sv2Frame { + /// Maps a `Sv2Frame` to `Sv2Frame` by applying `fun`, + /// which is assumed to be a closure that converts `A` to `C` + pub fn map(self, fun: fn(A) -> C) -> Sv2Frame { + let serialized = self.serialized; + let header = self.header; + let payload = self.payload.map(fun); + Sv2Frame { + header, + payload, + serialized, + } + } +} + +impl TryFrom> for Sv2Frame { + type Error = Error; + + fn try_from(v: EitherFrame) -> Result { + match v { + EitherFrame::Sv2(frame) => Ok(frame), + EitherFrame::HandShake(_) => Err(Error::ExpectedSv2Frame), + } + } +} + + +/// Abstraction for a Noise Handshake Frame +/// Contains only a `Slice` payload with a fixed length +/// Only used during Noise Handshake process +#[derive(Debug)] +pub struct HandShakeFrame { + payload: Slice, +} + impl HandShakeFrame { /// Put the Noise Frame payload into `dst` #[inline] @@ -196,6 +230,11 @@ impl HandShakeFrame { &mut self.payload[NOISE_HEADER_SIZE..] } + /// Returns payload of `HandShakeFrame` as a `Vec` + pub fn get_payload_when_handshaking(&self) -> Vec { + self.payload[0..].to_vec() + } + /// `HandShakeFrame` always returns `None`. fn get_header(&self) -> Option { None @@ -261,6 +300,18 @@ impl HandShakeFrame { } } +impl TryFrom> for HandShakeFrame { + type Error = Error; + + fn try_from(v: EitherFrame) -> Result { + match v { + EitherFrame::HandShake(frame) => Ok(frame), + EitherFrame::Sv2(_) => Err(Error::ExpectedHandshakeFrame), + } + } +} + + /// Returns a `HandShakeFrame` from a generic byte array #[allow(clippy::useless_conversion)] pub fn handshake_message_to_frame>(message: T) -> HandShakeFrame { @@ -285,57 +336,6 @@ fn update_extension_type(extension_type: u16, channel_msg: bool) -> u16 { } } -/// A wrapper to be used in a context we need a generic reference to a frame -/// but it doesn't matter which kind of frame it is (`Sv2Frame` or `HandShakeFrame`) -#[derive(Debug)] -pub enum EitherFrame { - HandShake(HandShakeFrame), - Sv2(Sv2Frame), -} - -impl + AsRef<[u8]>> EitherFrame { - pub fn encoded_length(&self) -> usize { - match &self { - Self::HandShake(frame) => frame.encoded_length(), - Self::Sv2(frame) => frame.encoded_length(), - } - } -} - -impl TryFrom> for HandShakeFrame { - type Error = Error; - - fn try_from(v: EitherFrame) -> Result { - match v { - EitherFrame::HandShake(frame) => Ok(frame), - EitherFrame::Sv2(_) => Err(Error::ExpectedHandshakeFrame), - } - } -} - -impl TryFrom> for Sv2Frame { - type Error = Error; - - fn try_from(v: EitherFrame) -> Result { - match v { - EitherFrame::Sv2(frame) => Ok(frame), - EitherFrame::HandShake(_) => Err(Error::ExpectedSv2Frame), - } - } -} - -impl From for EitherFrame { - fn from(v: HandShakeFrame) -> Self { - Self::HandShake(v) - } -} - -impl From> for EitherFrame { - fn from(v: Sv2Frame) -> Self { - Self::Sv2(v) - } -} - #[cfg(test)] use binary_sv2::binary_codec_sv2; From 4368dbd1d6a813a631301cdbfc1132bf5fb720ce Mon Sep 17 00:00:00 2001 From: jbesraa Date: Wed, 19 Jun 2024 12:26:32 +0300 Subject: [PATCH 8/9] Remove unused functions from `HandShakeFrame` --- protocols/v2/framing-sv2/src/framing.rs | 69 +------------------------ 1 file changed, 1 insertion(+), 68 deletions(-) diff --git a/protocols/v2/framing-sv2/src/framing.rs b/protocols/v2/framing-sv2/src/framing.rs index 23f3c18d06..3ce948594a 100644 --- a/protocols/v2/framing-sv2/src/framing.rs +++ b/protocols/v2/framing-sv2/src/framing.rs @@ -1,14 +1,8 @@ -#![allow(dead_code)] -use crate::{ - header::{Header, NOISE_HEADER_LEN_OFFSET, NOISE_HEADER_SIZE}, - Error, -}; +use crate::{header::Header, Error}; use alloc::vec::Vec; use binary_sv2::{to_writer, GetSize, Serialize}; use core::convert::TryFrom; -const NOISE_MAX_LEN: usize = const_sv2::NOISE_FRAME_MAX_SIZE; - #[cfg(not(feature = "with_buffer_pool"))] type Slice = Vec; @@ -217,29 +211,11 @@ pub struct HandShakeFrame { } impl HandShakeFrame { - /// Put the Noise Frame payload into `dst` - #[inline] - fn serialize(mut self, dst: &mut [u8]) -> Result<(), Error> { - dst.swap_with_slice(self.payload.as_mut()); - Ok(()) - } - - /// Get the Noise Frame payload - #[inline] - fn payload(&mut self) -> &mut [u8] { - &mut self.payload[NOISE_HEADER_SIZE..] - } - /// Returns payload of `HandShakeFrame` as a `Vec` pub fn get_payload_when_handshaking(&self) -> Vec { self.payload[0..].to_vec() } - /// `HandShakeFrame` always returns `None`. - fn get_header(&self) -> Option { - None - } - /// Builds a `HandShakeFrame` from raw bytes. Nothing is assumed or checked about the correctness of the payload. pub fn from_bytes(bytes: Slice) -> Result { Ok(Self::from_bytes_unchecked(bytes)) @@ -250,54 +226,11 @@ impl HandShakeFrame { Self { payload: bytes } } - /// After parsing the expected `HandShakeFrame` size from `bytes`, this function helps to determine if this value - /// 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. - #[inline] - fn size_hint(bytes: &[u8]) -> isize { - if bytes.len() < NOISE_HEADER_SIZE { - return (NOISE_HEADER_SIZE - bytes.len()) as isize; - }; - - 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() - NOISE_HEADER_SIZE == expected_len { - 0 - } else { - expected_len as isize - (bytes.len() - NOISE_HEADER_SIZE) as isize - } - } - /// Returns the size of the `HandShakeFrame` payload. #[inline] fn encoded_length(&self) -> usize { self.payload.len() } - - /// Tries to build a `HandShakeFrame` frame from a byte slice. - /// Returns a `HandShakeFrame` if the size of the payload fits in the frame, `None` otherwise. - /// This is quite inefficient, and should be used only to build `HandShakeFrames` - // TODO check if is used only to build `HandShakeFrames` - #[allow(clippy::useless_conversion)] - fn from_message( - message: Slice, - _message_type: u8, - _extension_type: u16, - _channel_msg: bool, - ) -> Option { - if message.len() <= NOISE_MAX_LEN { - Some(Self { - payload: message.into(), - }) - } else { - None - } - } } impl TryFrom> for HandShakeFrame { From 5a2b01b7c0e9f4872d2dccaf30531d2b6355380f Mon Sep 17 00:00:00 2001 From: jbesraa Date: Wed, 19 Jun 2024 12:35:08 +0300 Subject: [PATCH 9/9] Rename `framing::EitherFrame` to `::Frame` --- protocols/v2/codec-sv2/src/decoder.rs | 13 +++++-------- protocols/v2/codec-sv2/src/encoder.rs | 4 ++-- protocols/v2/framing-sv2/src/framing.rs | 26 ++++++++++++------------- 3 files changed, 19 insertions(+), 24 deletions(-) diff --git a/protocols/v2/codec-sv2/src/decoder.rs b/protocols/v2/codec-sv2/src/decoder.rs index 9f5f8e89ac..4d1440018e 100644 --- a/protocols/v2/codec-sv2/src/decoder.rs +++ b/protocols/v2/codec-sv2/src/decoder.rs @@ -12,7 +12,7 @@ use framing_sv2::framing::HandShakeFrame; #[cfg(feature = "noise_sv2")] use framing_sv2::header::{NOISE_HEADER_ENCRYPTED_SIZE, NOISE_HEADER_SIZE}; use framing_sv2::{ - framing::{EitherFrame, Sv2Frame}, + framing::{Frame, Sv2Frame}, header::Header, }; #[cfg(feature = "noise_sv2")] @@ -36,7 +36,7 @@ use crate::State; #[cfg(feature = "noise_sv2")] pub type StandardNoiseDecoder = WithNoise; -pub type StandardEitherFrame = EitherFrame::Slice>; +pub type StandardEitherFrame = Frame::Slice>; pub type StandardSv2Frame = Sv2Frame::Slice>; pub type StandardDecoder = WithoutNoise; @@ -51,7 +51,7 @@ pub struct WithNoise { #[cfg(feature = "noise_sv2")] impl<'a, T: Serialize + GetSize + Deserialize<'a>, B: IsBuffer + AeadBuffer> WithNoise { #[inline] - pub fn next_frame(&mut self, state: &mut State) -> Result> { + pub fn next_frame(&mut self, state: &mut State) -> Result> { match state { State::HandShake(_) => unreachable!(), State::NotInitialized(msg_len) => { @@ -97,10 +97,7 @@ impl<'a, T: Serialize + GetSize + Deserialize<'a>, B: IsBuffer + AeadBuffer> Wit } #[inline] - fn decode_noise_frame( - &mut self, - noise_codec: &mut NoiseCodec, - ) -> Result> { + fn decode_noise_frame(&mut self, noise_codec: &mut NoiseCodec) -> Result> { match ( IsBuffer::len(&self.noise_buffer), IsBuffer::len(&self.sv2_buffer), @@ -148,7 +145,7 @@ impl<'a, T: Serialize + GetSize + Deserialize<'a>, B: IsBuffer + AeadBuffer> Wit } } - fn while_handshaking(&mut self) -> EitherFrame { + fn while_handshaking(&mut self) -> Frame { let src = self.noise_buffer.get_data_owned().as_mut().to_vec(); // below is inffalible as noise frame length has been already checked diff --git a/protocols/v2/codec-sv2/src/encoder.rs b/protocols/v2/codec-sv2/src/encoder.rs index 39d10f00bf..21618fda51 100644 --- a/protocols/v2/codec-sv2/src/encoder.rs +++ b/protocols/v2/codec-sv2/src/encoder.rs @@ -7,7 +7,7 @@ use core::convert::TryInto; use core::marker::PhantomData; use framing_sv2::framing::Sv2Frame; #[cfg(feature = "noise_sv2")] -use framing_sv2::framing::{EitherFrame, HandShakeFrame}; +use framing_sv2::framing::{Frame, HandShakeFrame}; #[allow(unused_imports)] pub use framing_sv2::header::NOISE_HEADER_ENCRYPTED_SIZE; @@ -43,7 +43,7 @@ pub struct NoiseEncoder { } #[cfg(feature = "noise_sv2")] -type Item = EitherFrame; +type Item = Frame; #[cfg(feature = "noise_sv2")] impl NoiseEncoder { diff --git a/protocols/v2/framing-sv2/src/framing.rs b/protocols/v2/framing-sv2/src/framing.rs index 3ce948594a..616d533542 100644 --- a/protocols/v2/framing-sv2/src/framing.rs +++ b/protocols/v2/framing-sv2/src/framing.rs @@ -12,12 +12,12 @@ type Slice = buffer_sv2::Slice; /// A wrapper to be used in a context we need a generic reference to a frame /// but it doesn't matter which kind of frame it is (`Sv2Frame` or `HandShakeFrame`) #[derive(Debug)] -pub enum EitherFrame { +pub enum Frame { HandShake(HandShakeFrame), Sv2(Sv2Frame), } -impl + AsRef<[u8]>> EitherFrame { +impl + AsRef<[u8]>> Frame { pub fn encoded_length(&self) -> usize { match &self { Self::HandShake(frame) => frame.encoded_length(), @@ -26,13 +26,13 @@ impl + AsRef<[u8]>> EitherFrame { } } -impl From for EitherFrame { +impl From for Frame { fn from(v: HandShakeFrame) -> Self { Self::HandShake(v) } } -impl From> for EitherFrame { +impl From> for Frame { fn from(v: Sv2Frame) -> Self { Self::Sv2(v) } @@ -190,18 +190,17 @@ impl Sv2Frame { } } -impl TryFrom> for Sv2Frame { +impl TryFrom> for Sv2Frame { type Error = Error; - fn try_from(v: EitherFrame) -> Result { + fn try_from(v: Frame) -> Result { match v { - EitherFrame::Sv2(frame) => Ok(frame), - EitherFrame::HandShake(_) => Err(Error::ExpectedSv2Frame), + Frame::Sv2(frame) => Ok(frame), + Frame::HandShake(_) => Err(Error::ExpectedSv2Frame), } } } - /// Abstraction for a Noise Handshake Frame /// Contains only a `Slice` payload with a fixed length /// Only used during Noise Handshake process @@ -233,18 +232,17 @@ impl HandShakeFrame { } } -impl TryFrom> for HandShakeFrame { +impl TryFrom> for HandShakeFrame { type Error = Error; - fn try_from(v: EitherFrame) -> Result { + fn try_from(v: Frame) -> Result { match v { - EitherFrame::HandShake(frame) => Ok(frame), - EitherFrame::Sv2(_) => Err(Error::ExpectedHandshakeFrame), + Frame::HandShake(frame) => Ok(frame), + Frame::Sv2(_) => Err(Error::ExpectedHandshakeFrame), } } } - /// Returns a `HandShakeFrame` from a generic byte array #[allow(clippy::useless_conversion)] pub fn handshake_message_to_frame>(message: T) -> HandShakeFrame {