parity-zcash/message/src/message/message_header.rs

97 lines
2.4 KiB
Rust

use common::Command;
use hash::H32;
use ser::{Reader, Serializable, Stream};
use zebra_crypto::checksum;
use zebra_network::Magic;
use Error;
#[derive(Debug, PartialEq)]
pub struct MessageHeader {
pub magic: Magic,
pub command: Command,
pub len: u32,
pub checksum: H32,
}
impl MessageHeader {
pub fn for_data(magic: Magic, command: Command, data: &[u8]) -> Self {
MessageHeader {
magic: magic,
command: command,
len: data.len() as u32,
checksum: checksum(data),
}
}
}
impl MessageHeader {
pub fn deserialize(data: &[u8], expected: Magic) -> Result<Self, Error> {
if data.len() != 24 {
return Err(Error::Deserialize);
}
let mut reader = Reader::new(data);
let magic: u32 = try!(reader.read());
let magic = Magic::from(magic);
if expected != magic {
return Err(Error::InvalidMagic);
}
let header = MessageHeader {
magic: magic,
command: try!(reader.read()),
len: try!(reader.read()),
checksum: try!(reader.read()),
};
Ok(header)
}
}
impl Serializable for MessageHeader {
fn serialize(&self, stream: &mut Stream) {
stream
.append(&self.magic)
.append(&self.command)
.append(&self.len)
.append(&self.checksum);
}
}
#[cfg(test)]
mod tests {
use super::MessageHeader;
use bytes::Bytes;
use ser::serialize;
use zebra_network::Network;
#[test]
fn test_message_header_serialization() {
let expected = "24e927646164647200000000000000001f000000ed52399b".into();
let header = MessageHeader {
magic: Network::Mainnet.magic(),
command: "addr".into(),
len: 0x1f,
checksum: "ed52399b".into(),
};
assert_eq!(serialize(&header), expected);
}
#[test]
fn test_message_header_deserialization() {
let raw: Bytes = "24e927646164647200000000000000001f000000ed52399b".into();
let expected = MessageHeader {
magic: Network::Mainnet.magic(),
command: "addr".into(),
len: 0x1f,
checksum: "ed52399b".into(),
};
assert_eq!(
expected,
MessageHeader::deserialize(&raw, Network::Mainnet.magic()).unwrap()
);
}
}