From c8ed2fa30473c89f3c0fc5e96603361e4318f1ec Mon Sep 17 00:00:00 2001 From: Youngjoon Lee <5462944+youngjoon-lee@users.noreply.github.com> Date: Mon, 9 Sep 2024 09:01:01 +0900 Subject: [PATCH] wip: coeff --- mixnet-rs/ordering/src/bin/coeff.rs | 274 +++++++++++++++++++++++++ mixnet-rs/ordering/src/iteration.rs | 2 +- mixnet-rs/ordering/src/lib.rs | 1 + mixnet-rs/ordering/src/main.rs | 3 +- mixnet-rs/ordering/src/ordercoeff.rs | 285 --------------------------- mixnet-rs/ordering/src/outputs.rs | 7 +- mixnet-rs/ordering/src/sequence.rs | 41 ++++ mixnet-rs/ordering/src/topology.rs | 3 +- 8 files changed, 322 insertions(+), 294 deletions(-) create mode 100644 mixnet-rs/ordering/src/bin/coeff.rs create mode 100644 mixnet-rs/ordering/src/lib.rs delete mode 100644 mixnet-rs/ordering/src/ordercoeff.rs create mode 100644 mixnet-rs/ordering/src/sequence.rs diff --git a/mixnet-rs/ordering/src/bin/coeff.rs b/mixnet-rs/ordering/src/bin/coeff.rs new file mode 100644 index 0000000..7e0ab05 --- /dev/null +++ b/mixnet-rs/ordering/src/bin/coeff.rs @@ -0,0 +1,274 @@ +use ordering::message::{DataMessage, SenderIdx}; + +pub enum Entry { + Data(DataMessage), + Noise(u32), // the number of consecutive noises +} + +fn load_sequence(path: &str) -> Vec { + let mut entries: Vec = Vec::new(); + + let mut reader = csv::ReaderBuilder::new() + .has_headers(false) + .from_path(path) + .unwrap(); + + for result in reader.records() { + let record = result.unwrap(); + let value = &record[0]; + + if let Ok(num) = value.parse::() { + assert!(num < 0); + entries.push(Entry::Noise(num.unsigned_abs())); + } else { + entries.push(Entry::Data(parse_data_msg(value))); + } + } + + entries +} + +fn parse_data_msg(value: &str) -> DataMessage { + let parts: Vec<&str> = value.split(':').collect(); + assert_eq!(parts.len(), 2); + DataMessage { + sender: parts[0].parse::().unwrap(), + msg_id: parts[1].parse::().unwrap(), + } +} + +pub fn casual_coeff(seq1: &[Entry], seq2: &[Entry]) -> u64 { + let mut i = 0; + let mut j = 0; + let mut coeff = 0; + + while i < seq1.len() && j < seq2.len() { + let mut found_pair = false; + if let (Entry::Data(msg1), Entry::Data(msg2)) = (&seq1[i], &seq2[j]) { + if msg1 == msg2 { + // Try to find the next pair of Data messages + let mut next_i = i + 1; + let mut next_j = j + 1; + + while next_i < seq1.len() && next_j < seq2.len() { + match (&seq1[next_i], &seq2[next_j]) { + // If there's matching noise, continue to the next element + (Entry::Noise(n1), Entry::Noise(n2)) => { + if n1 == n2 { + next_i += 1; + next_j += 1; + } else { + break; + } + } + // If there's a matching Data message, count the pair + (Entry::Data(next_msg1), Entry::Data(next_msg2)) => { + if next_msg1 == next_msg2 { + coeff += 1; // Count the adjacent pair + i = next_i; // Move i and j to the next DataMessage + j = next_j; + found_pair = true; + } + break; + } + _ => break, + } + } + } + } + + // Increment only if no matching pair was found + if !found_pair { + i += 1; + j += 1; + } + } + + coeff +} + +fn weak_coeff(seq1: &[Entry], seq2: &[Entry]) -> u64 { + let mut i = 0; + let mut j = 0; + let mut coeff = 0; + + while i < seq1.len() && j < seq2.len() { + // Skip noise in both sequences + while i < seq1.len() && matches!(seq1[i], Entry::Noise(_)) { + i += 1; + } + while j < seq2.len() && matches!(seq2[j], Entry::Noise(_)) { + j += 1; + } + + // Compare the DataMessages + if i < seq1.len() && j < seq2.len() { + if let (Entry::Data(msg1), Entry::Data(msg2)) = (&seq1[i], &seq2[j]) { + if msg1 == msg2 { + // Now check the next pair + let mut next_i = i + 1; + let mut next_j = j + 1; + + // Skip noise in both sequences for the next pair + while next_i < seq1.len() && matches!(seq1[next_i], Entry::Noise(_)) { + next_i += 1; + } + while next_j < seq2.len() && matches!(seq2[next_j], Entry::Noise(_)) { + next_j += 1; + } + + // If the next pair of DataMessages match, count it + if next_i < seq1.len() && next_j < seq2.len() { + if let (Entry::Data(next_msg1), Entry::Data(next_msg2)) = + (&seq1[next_i], &seq2[next_j]) + { + if next_msg1 == next_msg2 { + coeff += 1; // Found a matching adjacent pair + i = next_i; + j = next_j; + continue; + } + } + } + } + } + } + + i += 1; + j += 1; + } + + coeff +} + +fn main() { + let seq1 = load_sequence("/Users/yjlee/repos/nomos-simulations/mixnet-rs/results/ordering_e5s1_PureCoinFlipping_2024-09-01T19:30:03.957310+00:00_0d0h12m25s/paramset_1/iteration_0_0d0h0m2s/sent_seq_0.csv"); + let seq2 = load_sequence("/Users/yjlee/repos/nomos-simulations/mixnet-rs/results/ordering_e5s1_PureCoinFlipping_2024-09-01T19:30:03.957310+00:00_0d0h12m25s/paramset_1/iteration_0_0d0h0m2s/recv_seq_0.csv"); + println!("casual:{:?}", casual_coeff(&seq1, &seq2)); + println!("weak:{:?}", weak_coeff(&seq1, &seq2)); +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_casual_coeff() { + // Empty sequences + assert_eq!(casual_coeff(&[], &[]), 0); + + // One matching pair without noise + let seq = vec![data(1), data(2)]; + assert_eq!(casual_coeff(&seq, &seq), 1); + + // One matching pair with noise + let seq = vec![data(1), noise(10), data(2)]; + assert_eq!(casual_coeff(&seq, &seq), 1); + + // One matching pair without noise from different sequences + let seq1 = vec![data(1), data(2), data(3)]; + let seq2 = vec![data(1), data(2), data(4)]; + assert_eq!(casual_coeff(&seq1, &seq2), 1); + let seq1 = vec![data(4), data(2), data(3)]; + let seq2 = vec![data(1), data(2), data(3)]; + assert_eq!(casual_coeff(&seq1, &seq2), 1); + + // One matching pair with noise from different sequences + let seq1 = vec![data(1), noise(10), data(2), data(3)]; + let seq2 = vec![data(1), noise(10), data(2), data(4)]; + assert_eq!(casual_coeff(&seq1, &seq2), 1); + let seq1 = vec![data(4), data(2), noise(10), data(3)]; + let seq2 = vec![data(1), data(2), noise(10), data(3)]; + assert_eq!(casual_coeff(&seq1, &seq2), 1); + + // Two pairs with noise + let seq1 = vec![data(1), noise(10), data(2), data(3)]; + let seq2 = vec![data(1), noise(10), data(2), data(3), data(4)]; + assert_eq!(casual_coeff(&seq1, &seq2), 2); + + // No match + let seq1 = vec![data(1), data(2)]; + let seq2 = vec![data(2), data(3)]; + assert_eq!(casual_coeff(&seq1, &seq2), 0); + let seq1 = vec![data(1), data(2)]; + let seq2 = vec![data(3), data(4)]; + assert_eq!(casual_coeff(&seq1, &seq2), 0); + + // No match because of noise + let seq1 = vec![data(1), noise(10), data(2)]; + let seq2 = vec![data(1), data(2)]; + assert_eq!(casual_coeff(&seq1, &seq2), 0); + let seq1 = vec![data(1), noise(10), data(2)]; + let seq2 = vec![data(1), noise(5), data(2)]; + assert_eq!(casual_coeff(&seq1, &seq2), 0); + + // No match because of mixed order + let seq1 = vec![data(1), data(2), data(3)]; + let seq2 = vec![data(2), data(3), data(4)]; + assert_eq!(casual_coeff(&seq1, &seq2), 0); + } + + #[test] + fn test_weak_coeff() { + // Empty sequences + assert_eq!(weak_coeff(&[], &[]), 0); + + // One matching pair without noise + let seq = vec![data(1), data(2)]; + assert_eq!(weak_coeff(&seq, &seq), 1); + + // One matching pair with noise + let seq = vec![data(1), noise(10), data(2)]; + assert_eq!(weak_coeff(&seq, &seq), 1); + + // One matching pair without noise from different sequences + let seq1 = vec![data(1), data(2), data(3)]; + let seq2 = vec![data(1), data(2), data(4)]; + assert_eq!(weak_coeff(&seq1, &seq2), 1); + let seq1 = vec![data(4), data(2), data(3)]; + let seq2 = vec![data(1), data(2), data(3)]; + assert_eq!(weak_coeff(&seq1, &seq2), 1); + + // One matching pair with noise from different sequences + let seq1 = vec![data(1), noise(10), data(2), data(3)]; + let seq2 = vec![data(1), noise(5), data(2), data(4)]; + assert_eq!(weak_coeff(&seq1, &seq2), 1); + let seq1 = vec![data(4), data(2), noise(10), data(3)]; + let seq2 = vec![data(1), data(2), noise(5), data(3)]; + assert_eq!(weak_coeff(&seq1, &seq2), 1); + let seq1 = vec![data(4), data(2), noise(10), data(3)]; + let seq2 = vec![data(1), data(2), data(3)]; + assert_eq!(weak_coeff(&seq1, &seq2), 1); + + // Two pairs with noise + let seq1 = vec![data(1), noise(10), data(2), data(3)]; + let seq2 = vec![data(1), noise(5), data(2), data(3), data(4)]; + assert_eq!(weak_coeff(&seq1, &seq2), 2); + + // No match + let seq1 = vec![data(1), data(2)]; + let seq2 = vec![data(2), data(3)]; + assert_eq!(weak_coeff(&seq1, &seq2), 0); + let seq1 = vec![data(1), data(2)]; + let seq2 = vec![data(3), data(4)]; + assert_eq!(weak_coeff(&seq1, &seq2), 0); + + // No match because of mixed order + let seq1 = vec![data(1), data(2), data(3)]; + let seq2 = vec![data(2), data(3), data(4)]; + assert_eq!(weak_coeff(&seq1, &seq2), 0); + + // One pair despite mixed order, because the order is mixed due to only noises. + let seq1 = vec![data(1), data(2), data(3)]; + let seq2 = vec![noise(10), data(1), data(2)]; + assert_eq!(weak_coeff(&seq1, &seq2), 1); + } + + fn data(msg_id: u32) -> Entry { + Entry::Data(DataMessage { sender: 0, msg_id }) + } + + fn noise(count: u32) -> Entry { + Entry::Noise(count) + } +} diff --git a/mixnet-rs/ordering/src/iteration.rs b/mixnet-rs/ordering/src/iteration.rs index 31e5d57..4c927cc 100644 --- a/mixnet-rs/ordering/src/iteration.rs +++ b/mixnet-rs/ordering/src/iteration.rs @@ -9,11 +9,11 @@ use rustc_hash::FxHashMap; use crate::{ format_duration, - message::{DataMessage, DataMessageGenerator}, outputs::Outputs, paramset::ParamSet, topology::{build_random_network, build_striped_network, RECEIVER_NODE_ID}, }; +use ordering::message::{DataMessage, DataMessageGenerator}; pub struct Iteration { pub paramset: ParamSet, diff --git a/mixnet-rs/ordering/src/lib.rs b/mixnet-rs/ordering/src/lib.rs new file mode 100644 index 0000000..e216a50 --- /dev/null +++ b/mixnet-rs/ordering/src/lib.rs @@ -0,0 +1 @@ +pub mod message; diff --git a/mixnet-rs/ordering/src/main.rs b/mixnet-rs/ordering/src/main.rs index 7e86913..5d237c4 100644 --- a/mixnet-rs/ordering/src/main.rs +++ b/mixnet-rs/ordering/src/main.rs @@ -1,8 +1,7 @@ mod iteration; -mod message; -mod ordercoeff; mod outputs; mod paramset; +mod sequence; mod topology; use std::{ diff --git a/mixnet-rs/ordering/src/ordercoeff.rs b/mixnet-rs/ordering/src/ordercoeff.rs deleted file mode 100644 index dd3a655..0000000 --- a/mixnet-rs/ordering/src/ordercoeff.rs +++ /dev/null @@ -1,285 +0,0 @@ -use std::fs::File; - -use crate::message::DataMessage; - -#[derive(Debug)] -pub struct SequenceWriter { - noise_buf: u32, - writer: csv::Writer, -} - -impl SequenceWriter { - pub fn new(path: &str) -> Self { - Self { - noise_buf: 0, - writer: csv::Writer::from_path(path).unwrap(), - } - } - - pub fn flush(&mut self) { - self.clear_buf(); - self.writer.flush().unwrap(); - } - - fn clear_buf(&mut self) { - if self.noise_buf > 0 { - self.writer - .write_record(&[format!("-{}", self.noise_buf)]) - .unwrap(); - self.noise_buf = 0; - } - } - - pub fn add_message(&mut self, msg: &DataMessage) { - self.clear_buf(); - self.writer.write_record(&[msg.to_string()]).unwrap(); - } - - pub fn add_noise(&mut self) { - self.noise_buf += 1; - } -} - -// impl Sequence { -// pub fn ordering_coefficient(&self, other: &Sequence, casual: bool) -> u64 { -// let mut coeff = 0; -// let mut i = 0; - -// while i < self.0.len() { -// if let Entry::Data(_) = &self.0[i] { -// let (c, next_i) = self.ordering_coefficient_from(i, other, casual); -// coeff += c; - -// if next_i != i { -// i = next_i; -// } else { -// i += 1; -// } -// } else { -// i += 1; -// } -// } - -// coeff -// } - -// fn ordering_coefficient_from( -// &self, -// start_idx: usize, -// other: &Sequence, -// casual: bool, -// ) -> (u64, usize) { -// let msg1 = match self.0[start_idx] { -// Entry::Data(msg) => msg, -// _ => panic!("Entry at {start_idx} must be Message"), -// }; - -// for (j, entry) in other.iter().enumerate() { -// if let Entry::Data(msg2) = entry { -// if msg1 == *msg2 { -// // Found the 1st matching msg. Start finding the next adjacent matching msg. -// if casual { -// return self.casual_ordering_coefficient_from(start_idx, other, j); -// } else { -// return self.weak_ordering_coefficient_from(start_idx, other, j); -// } -// } -// } -// } -// (0, start_idx) -// } - -// fn casual_ordering_coefficient_from( -// &self, -// start_idx: usize, -// other: &Sequence, -// other_start_idx: usize, -// ) -> (u64, usize) { -// let mut coeff = 0; -// let mut i = start_idx + 1; -// let mut j = other_start_idx + 1; -// while i < self.0.len() && j < other.0.len() { -// match (&self.0[i], &other.0[j]) { -// (Entry::Noise(cnt1), Entry::Noise(cnt2)) => { -// if cnt1 == cnt2 { -// i += 1; -// j += 1; -// } else { -// break; -// } -// } -// (Entry::Data(msg1), Entry::Data(msg2)) => { -// if msg1 == msg2 { -// coeff += 1; -// i += 1; -// j += 1; -// } else { -// break; -// } -// } -// _ => break, -// } -// } -// (coeff, i) -// } - -// fn weak_ordering_coefficient_from( -// &self, -// start_idx: usize, -// other: &Sequence, -// other_start_idx: usize, -// ) -> (u64, usize) { -// let mut coeff = 0; -// let mut i = start_idx + 1; -// let mut j = other_start_idx + 1; -// while i < self.0.len() && j < other.0.len() { -// i = self.skip_noise(i); -// j = other.skip_noise(j); -// if i < self.0.len() && j < other.0.len() && self.0[i] == other.0[j] { -// coeff += 1; -// i += 1; -// j += 1; -// } else { -// break; -// } -// } -// (coeff, i) -// } - -// fn skip_noise(&self, mut index: usize) -> usize { -// while index < self.0.len() { -// if let Entry::Data(_) = self.0[index] { -// break; -// } -// index += 1; -// } -// index -// } -// } - -// #[cfg(test)] -// mod tests { -// use super::*; - -// fn test_ordering_coefficient_common(casual: bool) { -// // Case 0: Empty sequences -// let seq = Sequence(vec![]); -// assert_eq!(seq.ordering_coefficient(&seq, casual), 0); - -// // Case 1: Exact one matched pair with no noise -// let seq = Sequence(vec![Entry::Data(1), Entry::Data(2)]); -// assert_eq!(seq.ordering_coefficient(&seq, casual), 1); - -// // Case 2: Exact one matched pair with noise -// let seq = Sequence(vec![Entry::Data(1), Entry::Noise(10), Entry::Data(2)]); -// assert_eq!(seq.ordering_coefficient(&seq, casual), 1); - -// // Case 3: One matched pair with no noise -// let seq1 = Sequence(vec![Entry::Data(1), Entry::Data(2), Entry::Data(3)]); -// let seq2 = Sequence(vec![Entry::Data(1), Entry::Data(2), Entry::Data(4)]); -// assert_eq!(seq1.ordering_coefficient(&seq2, casual), 1); -// assert_eq!(seq2.ordering_coefficient(&seq1, casual), 1); - -// // Case 4: One matched pair with noise -// let seq1 = Sequence(vec![ -// Entry::Data(1), -// Entry::Noise(10), -// Entry::Data(2), -// Entry::Data(3), -// ]); -// let seq2 = Sequence(vec![Entry::Data(1), Entry::Noise(10), Entry::Data(2)]); -// assert_eq!(seq1.ordering_coefficient(&seq2, casual), 1); -// assert_eq!(seq2.ordering_coefficient(&seq1, casual), 1); - -// // Case 5: Two matched pairs with noise -// let seq1 = Sequence(vec![ -// Entry::Data(1), -// Entry::Noise(10), -// Entry::Data(2), -// Entry::Data(3), -// ]); -// let seq2 = Sequence(vec![ -// Entry::Data(1), -// Entry::Noise(10), -// Entry::Data(2), -// Entry::Data(3), -// Entry::Data(4), -// ]); -// assert_eq!(seq1.ordering_coefficient(&seq2, casual), 2); -// assert_eq!(seq2.ordering_coefficient(&seq1, casual), 2); - -// // Case 6: Only partial match with no noise -// let seq1 = Sequence(vec![Entry::Data(1), Entry::Data(2)]); -// let seq2 = Sequence(vec![Entry::Data(2), Entry::Data(3)]); -// assert_eq!(seq1.ordering_coefficient(&seq2, casual), 0); -// assert_eq!(seq2.ordering_coefficient(&seq1, casual), 0); - -// // Case 7: Only partial match with noise -// let seq1 = Sequence(vec![Entry::Data(1), Entry::Data(2), Entry::Noise(10)]); -// let seq2 = Sequence(vec![Entry::Data(2), Entry::Noise(10), Entry::Data(3)]); -// assert_eq!(seq1.ordering_coefficient(&seq2, casual), 0); -// assert_eq!(seq2.ordering_coefficient(&seq1, casual), 0); - -// // Case 8: No match at all -// let seq1 = Sequence(vec![Entry::Data(1), Entry::Data(2), Entry::Noise(10)]); -// let seq2 = Sequence(vec![Entry::Data(3), Entry::Noise(10), Entry::Data(4)]); -// assert_eq!(seq1.ordering_coefficient(&seq2, casual), 0); -// assert_eq!(seq2.ordering_coefficient(&seq1, casual), 0); - -// // Case 9: Matches with noise but mixed orders -// let seq1 = Sequence(vec![ -// Entry::Data(1), -// Entry::Data(2), -// Entry::Noise(10), -// Entry::Data(3), -// Entry::Data(4), -// Entry::Data(5), -// Entry::Data(6), -// ]); -// let seq2 = Sequence(vec![ -// Entry::Data(4), -// Entry::Data(5), -// Entry::Data(1), -// Entry::Data(2), -// Entry::Noise(10), -// Entry::Data(3), -// Entry::Data(6), -// ]); -// assert_eq!(seq1.ordering_coefficient(&seq2, casual), 3); -// assert_eq!(seq2.ordering_coefficient(&seq1, casual), 3); -// } - -// #[test] -// fn test_casual_ordering_coefficient() { -// test_ordering_coefficient_common(true); - -// // Case 0: No match because of noise -// let seq1 = Sequence(vec![Entry::Data(1), Entry::Noise(10), Entry::Data(2)]); -// let seq2 = Sequence(vec![Entry::Data(1), Entry::Data(2)]); -// assert_eq!(seq1.ordering_coefficient(&seq2, true), 0); -// assert_eq!(seq2.ordering_coefficient(&seq1, true), 0); - -// // Case 1: No match because of different count of noises -// let seq1 = Sequence(vec![Entry::Data(1), Entry::Noise(10), Entry::Data(2)]); -// let seq2 = Sequence(vec![Entry::Data(1), Entry::Noise(5), Entry::Data(2)]); -// assert_eq!(seq1.ordering_coefficient(&seq2, true), 0); -// assert_eq!(seq2.ordering_coefficient(&seq1, true), 0); -// } - -// #[test] -// fn test_weak_ordering_coefficient() { -// test_ordering_coefficient_common(false); - -// // Case 0: Match ignoring noises -// let seq1 = Sequence(vec![Entry::Data(1), Entry::Noise(10), Entry::Data(2)]); -// let seq2 = Sequence(vec![Entry::Data(1), Entry::Data(2)]); -// assert_eq!(seq1.ordering_coefficient(&seq2, false), 1); -// assert_eq!(seq2.ordering_coefficient(&seq1, false), 1); - -// // Case 1: Match ignoring noise count -// let seq1 = Sequence(vec![Entry::Data(1), Entry::Noise(10), Entry::Data(2)]); -// let seq2 = Sequence(vec![Entry::Data(1), Entry::Noise(5), Entry::Data(2)]); -// assert_eq!(seq1.ordering_coefficient(&seq2, false), 1); -// assert_eq!(seq2.ordering_coefficient(&seq1, false), 1); -// } -// } diff --git a/mixnet-rs/ordering/src/outputs.rs b/mixnet-rs/ordering/src/outputs.rs index 06c34da..61922ed 100644 --- a/mixnet-rs/ordering/src/outputs.rs +++ b/mixnet-rs/ordering/src/outputs.rs @@ -5,11 +5,8 @@ use protocol::{ topology::Topology, }; -use crate::{ - message::{DataMessage, SenderIdx}, - ordercoeff::SequenceWriter, - topology::AllSenderPeers, -}; +use crate::{sequence::SequenceWriter, topology::AllSenderPeers}; +use ordering::message::{DataMessage, SenderIdx}; pub struct Outputs { closed: bool, diff --git a/mixnet-rs/ordering/src/sequence.rs b/mixnet-rs/ordering/src/sequence.rs new file mode 100644 index 0000000..8b26cfb --- /dev/null +++ b/mixnet-rs/ordering/src/sequence.rs @@ -0,0 +1,41 @@ +use std::fs::File; + +use ordering::message::DataMessage; + +#[derive(Debug)] +pub struct SequenceWriter { + noise_buf: u32, + writer: csv::Writer, +} + +impl SequenceWriter { + pub fn new(path: &str) -> Self { + Self { + noise_buf: 0, + writer: csv::Writer::from_path(path).unwrap(), + } + } + + pub fn flush(&mut self) { + self.clear_buf(); + self.writer.flush().unwrap(); + } + + fn clear_buf(&mut self) { + if self.noise_buf > 0 { + self.writer + .write_record(&[format!("-{}", self.noise_buf)]) + .unwrap(); + self.noise_buf = 0; + } + } + + pub fn add_message(&mut self, msg: &DataMessage) { + self.clear_buf(); + self.writer.write_record(&[msg.to_string()]).unwrap(); + } + + pub fn add_noise(&mut self) { + self.noise_buf += 1; + } +} diff --git a/mixnet-rs/ordering/src/topology.rs b/mixnet-rs/ordering/src/topology.rs index 8a78f39..bbe3bfc 100644 --- a/mixnet-rs/ordering/src/topology.rs +++ b/mixnet-rs/ordering/src/topology.rs @@ -8,7 +8,8 @@ use protocol::{ use rand::{rngs::StdRng, seq::SliceRandom, RngCore, SeedableRng}; use rustc_hash::FxHashMap; -use crate::{message::SenderIdx, outputs::Outputs, paramset::ParamSet}; +use crate::{outputs::Outputs, paramset::ParamSet}; +use ordering::message::SenderIdx; pub const RECEIVER_NODE_ID: NodeId = NodeId::MAX;