From 7b1983013daedc44404a1826b51a7fe95790416e Mon Sep 17 00:00:00 2001 From: debris Date: Mon, 19 Sep 2016 18:36:48 +0200 Subject: [PATCH] inventory vector --- Cargo.lock | 1 + net/Cargo.toml | 1 + net/src/inventory.rs | 108 +++++++++++++++++++++++++++++++++++++++++++ net/src/lib.rs | 5 ++ 4 files changed, 115 insertions(+) create mode 100644 net/src/inventory.rs diff --git a/Cargo.lock b/Cargo.lock index 375d6749..cd20c485 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -102,6 +102,7 @@ name = "net" version = "0.1.0" dependencies = [ "byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "primitives 0.1.0", "serialization 0.1.0", ] diff --git a/net/Cargo.toml b/net/Cargo.toml index 874e8438..9893af81 100644 --- a/net/Cargo.toml +++ b/net/Cargo.toml @@ -6,5 +6,6 @@ authors = ["debris "] [dependencies] byteorder = "0.5" +primitives = { path = "../primitives" } serialization = { path = "../serialization" } diff --git a/net/src/inventory.rs b/net/src/inventory.rs new file mode 100644 index 00000000..796546cd --- /dev/null +++ b/net/src/inventory.rs @@ -0,0 +1,108 @@ +use hash::H256; +use ser::{Serializable, Stream, Deserializable, Reader, Error as ReaderError}; + +#[derive(Debug, PartialEq, Clone, Copy)] +#[repr(u8)] +pub enum InventoryType { + Error = 0, + MessageTx = 1, + MessageBlock = 2, + MessageFilteredBlock = 3, + MessageCompactBlock = 4, +} + +impl InventoryType { + pub fn from_u32(v: u32) -> Option { + match v { + 0 => Some(InventoryType::Error), + 1 => Some(InventoryType::MessageTx), + 2 => Some(InventoryType::MessageBlock), + 3 => Some(InventoryType::MessageFilteredBlock), + 4 => Some(InventoryType::MessageCompactBlock), + _ => None + } + } +} + +impl From for u32 { + fn from(i: InventoryType) -> Self { + i as u32 + } +} + +#[derive(Debug, PartialEq)] +pub struct InventoryVector { + pub inv_type: u32, + pub hash: H256, +} + +impl Serializable for InventoryVector { + fn serialize(&self, stream: &mut Stream) { + stream + .append(&self.inv_type) + .append(&self.hash); + } +} + +impl Deserializable for InventoryVector { + fn deserialize(reader: &mut Reader) -> Result where Self: Sized { + let vec = InventoryVector { + inv_type: try!(reader.read()), + hash: try!(reader.read()), + }; + + Ok(vec) + } +} + +impl InventoryVector { + pub fn inventory_type(&self) -> Option { + InventoryType::from_u32(self.inv_type) + } +} + +#[cfg(test)] +mod tests { + use bytes::Bytes; + use ser::{serialize, deserialize}; + use super::{InventoryVector, InventoryType}; + + #[test] + fn test_inventory_serialize() { + let expected = "020000000000000000000000000000000000000000000000000000000000000000000004".into(); + + let inventory = InventoryVector { + inv_type: 2, + hash: 4u8.into(), + }; + + assert_eq!(serialize(&inventory), expected); + } + + #[test] + fn test_inventory_deserialize() { + let raw: Bytes = "020000000000000000000000000000000000000000000000000000000000000000000004".into(); + + let expected = InventoryVector { + inv_type: 2, + hash: 4u8.into(), + }; + + assert_eq!(expected, deserialize(&raw).unwrap()); + } + + #[test] + fn test_inventory_type_conversion() { + assert_eq!(0u32, InventoryType::Error.into()); + assert_eq!(1u32, InventoryType::MessageTx.into()); + assert_eq!(2u32, InventoryType::MessageBlock.into()); + assert_eq!(3u32, InventoryType::MessageFilteredBlock.into()); + assert_eq!(4u32, InventoryType::MessageCompactBlock.into()); + + assert_eq!(InventoryType::from_u32(0).unwrap(), InventoryType::Error); + assert_eq!(InventoryType::from_u32(1).unwrap(), InventoryType::MessageTx); + assert_eq!(InventoryType::from_u32(2).unwrap(), InventoryType::MessageBlock); + assert_eq!(InventoryType::from_u32(3).unwrap(), InventoryType::MessageFilteredBlock); + assert_eq!(InventoryType::from_u32(4).unwrap(), InventoryType::MessageCompactBlock); + } +} diff --git a/net/src/lib.rs b/net/src/lib.rs index 1a514c3c..b3231182 100644 --- a/net/src/lib.rs +++ b/net/src/lib.rs @@ -1,12 +1,17 @@ extern crate byteorder; +extern crate primitives; extern crate serialization as ser; mod address; +mod inventory; mod ip; mod port; mod service; +pub use primitives::{hash, bytes}; + pub use self::address::NetAddress; +pub use self::inventory::{InventoryVector, InventoryType}; pub use self::ip::IpAddress; pub use self::port::Port; pub use self::service::ServiceFlags;