pub fn get_debug_id(input: Vec<u8>) -> ::std::string::String {
format!("BYTES:{:02x}{:02x}{:02x}..{:02x}{:02x}{:02x}",
input[0],
input[1],
input[2],
input[input.len()-3],
input[input.len()-2],
input[input.len()-1])
}
pub fn encode<T>(value: &T) -> Result<Vec<u8>, ::cbor::CborError>
where T: ::rustc_serialize::Encodable
{
let mut enc = ::cbor::Encoder::from_memory();
try!(enc.encode(&[value]));
Ok(enc.into_bytes())
}
pub fn decode<T>(bytes: &Vec<u8>) -> Result<T, ::cbor::CborError>
where T: ::rustc_serialize::Decodable
{
let mut dec = ::cbor::Decoder::from_bytes(&bytes[..]);
match dec.decode().next() {
Some(result) => result,
None => Err(::cbor::CborError::UnexpectedEOF),
}
}
pub fn public_key_to_client_name(key: &::sodiumoxide::crypto::sign::PublicKey) -> ::NameType {
::NameType(::sodiumoxide::crypto::hash::sha512::hash(&key[..]).0)
}
pub fn calculate_relocated_name(mut close_nodes: Vec<::NameType>, original_name: &::NameType)
-> Result<::NameType, ::error::RoutingError> {
if close_nodes.is_empty() {
return Err(::error::RoutingError::RoutingTableEmpty);
}
close_nodes.sort_by(|a, b| if ::name_type::closer_to_target(&a, &b, original_name) {
::std::cmp::Ordering::Less
} else {
::std::cmp::Ordering::Greater
});
close_nodes.truncate(2usize);
close_nodes.insert(0, original_name.clone());
let mut combined: Vec<u8> = Vec::new();
for node_id in close_nodes {
for i in node_id.get_id().iter() {
combined.push(*i);
}
}
Ok(::NameType(::sodiumoxide::crypto::hash::sha512::hash(&combined).0))
}
#[cfg(test)]
mod test {
#[test]
fn public_key_to_client_name() {
let sign_keys = ::sodiumoxide::crypto::sign::gen_keypair();
let client_name = super::public_key_to_client_name(&sign_keys.0);
let name = ::NameType(::sodiumoxide::crypto::hash::sha512::hash(&sign_keys.0[..]).0);
assert_eq!(client_name, name);
}
#[test]
fn encode_decode() {
let name: ::NameType = ::test_utils::Random::generate_random();
let encoded = match super::encode(&name) {
Ok(encoded) => encoded,
Err(_) => panic!("Unexpected serialisation error.")
};
let decoded = match super::decode(&encoded) {
Ok(decoded) => decoded,
Err(_) => panic!("Unexpected deserialisation error.")
};
assert_eq!(name, ::NameType(::types::vector_as_u8_64_array(decoded)));
}
#[test]
fn calculate_relocated_name() {
let original_name : ::NameType = ::test_utils::Random::generate_random();
assert!(super::calculate_relocated_name(Vec::new(), &original_name).is_err());
let mut close_nodes_one_entry : Vec<::NameType> = Vec::new();
close_nodes_one_entry.push(::test_utils::Random::generate_random());
let actual_relocated_name_one_entry =
super::calculate_relocated_name(close_nodes_one_entry.clone(),
&original_name).unwrap();
assert!(original_name != actual_relocated_name_one_entry);
let mut combined_one_node_vec : Vec<::NameType> = Vec::new();
combined_one_node_vec.push(original_name.clone());
combined_one_node_vec.push(close_nodes_one_entry[0].clone());
let mut combined_one_node: Vec<u8> = Vec::new();
for node_id in combined_one_node_vec {
for i in node_id.get_id().iter() {
combined_one_node.push(*i);
}
}
let expected_relocated_name_one_node =
::NameType(::sodiumoxide::crypto::hash::sha512::hash(&combined_one_node).0);
assert_eq!(actual_relocated_name_one_entry, expected_relocated_name_one_node);
let mut close_nodes : Vec<::NameType> = Vec::new();
for _ in 0..::types::GROUP_SIZE {
close_nodes.push(::test_utils::Random::generate_random());
}
let actual_relocated_name = super::calculate_relocated_name(close_nodes.clone(),
&original_name).unwrap();
assert!(original_name != actual_relocated_name);
close_nodes.sort_by(|a, b| if ::name_type::closer_to_target(&a, &b, &original_name) {
::std::cmp::Ordering::Less
} else {
::std::cmp::Ordering::Greater
});
let first_closest = close_nodes[0].clone();
let second_closest = close_nodes[1].clone();
let mut combined: Vec<u8> = Vec::new();
for i in original_name.get_id().into_iter() {
combined.push(*i);
}
for i in first_closest.get_id().into_iter() {
combined.push(*i);
}
for i in second_closest.get_id().into_iter() {
combined.push(*i);
}
let expected_relocated_name =
::NameType(::sodiumoxide::crypto::hash::sha512::hash(&combined).0);
assert_eq!(expected_relocated_name, actual_relocated_name);
let mut invalid_combined: Vec<u8> = Vec::new();
for i in first_closest.get_id().into_iter() {
invalid_combined.push(*i);
}
for i in second_closest.get_id().into_iter() {
invalid_combined.push(*i);
}
for i in original_name.get_id().into_iter() {
invalid_combined.push(*i);
}
let invalid_relocated_name =
::NameType(::sodiumoxide::crypto::hash::sha512::hash(&invalid_combined).0);
assert!(invalid_relocated_name != actual_relocated_name);
}
}