use prost::{encode_length_delimiter, length_delimiter_len};
mod time;
pub use time::SystemTimeExt;
mod priority_set;
pub use priority_set::PrioritySet;
pub fn hex(bytes: &[u8]) -> String {
let mut hex = String::new();
for byte in bytes.iter() {
hex.push_str(&format!("{:02x}", byte));
}
hex
}
pub fn from_hex(hex: &str) -> Option<Vec<u8>> {
if hex.len() % 2 != 0 {
return None;
}
(0..hex.len())
.step_by(2)
.map(|i| match u8::from_str_radix(&hex[i..i + 2], 16) {
Ok(byte) => Some(byte),
Err(_) => None,
})
.collect()
}
pub fn from_hex_formatted(hex: &str) -> Option<Vec<u8>> {
let hex = hex.replace(['\t', '\n', '\r', ' '], "");
let res = hex.strip_prefix("0x").unwrap_or(&hex);
from_hex(res)
}
pub fn max_faults(n: u32) -> Option<u32> {
let f = n.checked_sub(1)? / 3;
if f == 0 {
return None;
}
Some(f)
}
pub fn quorum(n: u32) -> Option<u32> {
let f = max_faults(n)?;
Some((2 * f) + 1)
}
pub fn union(a: &[u8], b: &[u8]) -> Vec<u8> {
let mut union = Vec::with_capacity(a.len() + b.len());
union.extend_from_slice(a);
union.extend_from_slice(b);
union
}
pub fn union_unique(namespace: &[u8], msg: &[u8]) -> Vec<u8> {
let ld_len = length_delimiter_len(namespace.len());
let mut result = Vec::with_capacity(ld_len + namespace.len() + msg.len());
encode_length_delimiter(namespace.len(), &mut result).unwrap();
result.extend_from_slice(namespace);
result.extend_from_slice(msg);
result
}
pub fn modulo(bytes: &[u8], n: u64) -> u64 {
let mut result = 0;
for &byte in bytes {
result = (result << 8) | (byte as u64);
result %= n;
}
result
}
pub trait SizedSerialize {
const SERIALIZED_LEN: usize;
}
impl SizedSerialize for u8 {
const SERIALIZED_LEN: usize = 1;
}
impl SizedSerialize for u16 {
const SERIALIZED_LEN: usize = 2;
}
impl SizedSerialize for u32 {
const SERIALIZED_LEN: usize = 4;
}
impl SizedSerialize for u64 {
const SERIALIZED_LEN: usize = 8;
}
#[cfg(test)]
mod tests {
use super::*;
use num_bigint::BigUint;
use rand::{rngs::StdRng, Rng, SeedableRng};
#[test]
fn test_hex() {
let b = &[];
let h = hex(b);
assert_eq!(h, "");
assert_eq!(from_hex(&h).unwrap(), b.to_vec());
let b = &[0x01];
let h = hex(b);
assert_eq!(h, "01");
assert_eq!(from_hex(&h).unwrap(), b.to_vec());
let b = &[0x01, 0x02, 0x03];
let h = hex(b);
assert_eq!(h, "010203");
assert_eq!(from_hex(&h).unwrap(), b.to_vec());
let h = "0102030";
assert!(from_hex(h).is_none());
let h = "01g3";
assert!(from_hex(h).is_none());
}
#[test]
fn test_from_hex_formatted() {
let b = &[];
let h = hex(b);
assert_eq!(h, "");
assert_eq!(from_hex_formatted(&h).unwrap(), b.to_vec());
let b = &[0x01];
let h = hex(b);
assert_eq!(h, "01");
assert_eq!(from_hex_formatted(&h).unwrap(), b.to_vec());
let b = &[0x01, 0x02, 0x03];
let h = hex(b);
assert_eq!(h, "010203");
assert_eq!(from_hex_formatted(&h).unwrap(), b.to_vec());
let h = "0102030";
assert!(from_hex_formatted(h).is_none());
let h = "01g3";
assert!(from_hex_formatted(h).is_none());
let h = "01 02 03";
assert_eq!(from_hex_formatted(h).unwrap(), b.to_vec());
let h = "0x010203";
assert_eq!(from_hex_formatted(h).unwrap(), b.to_vec());
let h = " \n\n0x\r\n01
02\t03\n";
assert_eq!(from_hex_formatted(h).unwrap(), b.to_vec());
}
#[test]
fn test_quorum() {
assert_eq!(quorum(3), None);
assert_eq!(quorum(4), Some(3));
assert_eq!(quorum(7), Some(5));
assert_eq!(quorum(10), Some(7));
}
#[test]
fn test_union() {
assert_eq!(union(&[], &[]), []);
assert_eq!(union(&[], &[0x01, 0x02, 0x03]), [0x01, 0x02, 0x03]);
assert_eq!(
union(&[0x01, 0x02, 0x03], &[0x04, 0x05, 0x06]),
[0x01, 0x02, 0x03, 0x04, 0x05, 0x06]
);
}
#[test]
fn test_union_unique() {
let namespace = b"namespace";
let msg = b"message";
let length_encoding = vec![0b0000_1001];
let mut expected = Vec::with_capacity(length_encoding.len() + namespace.len() + msg.len());
expected.extend_from_slice(&length_encoding);
expected.extend_from_slice(namespace);
expected.extend_from_slice(msg);
let result = union_unique(namespace, msg);
assert_eq!(result, expected);
assert_eq!(result.len(), result.capacity());
}
#[test]
fn test_union_unique_zero_length() {
let namespace = b"";
let msg = b"message";
let length_encoding = vec![0];
let mut expected = Vec::with_capacity(length_encoding.len() + namespace.len() + msg.len());
expected.extend_from_slice(&length_encoding);
expected.extend_from_slice(msg);
let result = union_unique(namespace, msg);
assert_eq!(result, expected);
assert_eq!(result.len(), result.capacity());
}
#[test]
fn test_union_unique_long_length() {
let namespace = &b"n".repeat(256);
let msg = b"message";
let length_encoding = vec![0b1000_0000, 0b0000_0010];
let mut expected = Vec::with_capacity(length_encoding.len() + namespace.len() + msg.len());
expected.extend_from_slice(&length_encoding);
expected.extend_from_slice(namespace);
expected.extend_from_slice(msg);
let result = union_unique(namespace, msg);
assert_eq!(result, expected);
assert_eq!(result.len(), result.capacity());
}
#[test]
fn test_modulo() {
assert_eq!(modulo(&[], 1), 0);
assert_eq!(modulo(&[0x01], 1), 0);
assert_eq!(modulo(&[0x01, 0x02, 0x03], 10), 1);
let n = 11u64;
for i in 0..100 {
let mut rng = StdRng::seed_from_u64(i);
let bytes: [u8; 32] = rng.gen();
let big_modulo = BigUint::from_bytes_be(&bytes) % n;
let utils_modulo = modulo(&bytes, n);
assert_eq!(big_modulo, BigUint::from(utils_modulo));
}
}
}