use std::io::{self, Read, Write};
mod header;
pub mod message;
pub(crate) mod payload;
pub trait Marshallable {
fn marshal_binary<W: Write>(&self, writer: &mut W) -> io::Result<()>;
fn unmarshal_binary<R: Read>(reader: &mut R) -> io::Result<Self>
where
Self: Sized;
}
#[cfg(test)]
mod tests {
use std::io::{BufReader, BufWriter, Cursor, Read, Seek};
use rand::RngCore;
use semver::Version;
use super::Marshallable;
use crate::encoding::header::Header;
use crate::encoding::message::Message;
use crate::encoding::payload::{
BroadcastPayload, NodePayload, PeerEncodedInfo,
};
use crate::peer::PeerNode;
use crate::tests::Result;
const VERSION: Version = Version::new(1, 0, 0);
#[test]
fn test_encode_ping() -> Result<()> {
let peer = PeerNode::generate("192.168.0.1:666", 0)?;
let a = Message::Ping(peer.to_header(), VERSION);
test_kadkast_marshal(a)
}
#[test]
fn test_encode_pong() -> Result<()> {
let peer = PeerNode::generate("192.168.0.1:666", 0)?;
let a = Message::Pong(peer.to_header(), VERSION);
test_kadkast_marshal(a)
}
#[test]
fn test_encode_find_nodes() -> Result<()> {
let peer = PeerNode::generate("192.168.0.1:666", 0)?;
let target =
*PeerNode::generate("192.168.1.1:666", 0)?.id().as_binary();
let a = Message::FindNodes(peer.to_header(), VERSION, target);
test_kadkast_marshal(a)
}
#[test]
fn test_encode_nodes() -> Result<()> {
let peer = PeerNode::generate("192.168.0.1:666", 0)?;
let nodes = vec![
PeerNode::generate("192.168.1.1:666", 0)?,
PeerNode::generate(
"[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:666",
0,
)?,
]
.iter()
.map(|f| f.as_peer_info())
.collect();
let a = Message::Nodes(
peer.to_header(),
VERSION,
NodePayload { peers: nodes },
);
test_kadkast_marshal(a)
}
#[test]
fn test_encode_empty_nodes() -> Result<()> {
let peer = PeerNode::generate("192.168.0.1:666", 0)?;
let a = Message::Nodes(
peer.to_header(),
VERSION,
NodePayload { peers: vec![] },
);
test_kadkast_marshal(a)
}
#[test]
fn test_encode_broadcast() -> Result<()> {
let peer = PeerNode::generate("192.168.0.1:666", 0)?;
let a = Message::broadcast(
peer.to_header(),
BroadcastPayload {
height: 10,
gossip_frame: vec![3, 5, 6, 7],
},
);
test_kadkast_marshal(a)
}
fn test_kadkast_marshal(messge: Message) -> Result<()> {
println!("orig: {:?}", messge);
let mut c = Cursor::new(Vec::new());
let mut writer = BufWriter::new(c);
messge.marshal_binary(&mut writer)?;
c = writer.into_inner()?;
let mut bytes = vec![];
c.seek(std::io::SeekFrom::Start(0))?;
c.read_to_end(&mut bytes)?;
println!("bytes: {:?}", bytes);
println!("byhex: {:02X?}", bytes);
let c = Cursor::new(bytes);
let mut reader = BufReader::new(c);
let deser = Message::unmarshal_binary(&mut reader)?;
println!("dese: {:?}", deser);
assert_eq!(messge, deser);
Ok(())
}
#[test]
fn test_failing() -> Result<()> {
let mut data = [0u8; 4];
rand::thread_rng().fill_bytes(&mut data);
println!("{:?}", data);
let mut reader = BufReader::new(&data[..]);
Message::unmarshal_binary(&mut reader)
.expect_err("Message::unmarshal_binary should fail");
let mut reader = BufReader::new(&data[..]);
Header::unmarshal_binary(&mut reader)
.expect_err("Header::unmarshal_binary should fail");
let mut reader = BufReader::new(&data[..]);
BroadcastPayload::unmarshal_binary(&mut reader)
.expect_err("BroadcastPayload::unmarshal_binary should fail");
let mut reader = BufReader::new(&data[..]);
NodePayload::unmarshal_binary(&mut reader)
.expect_err("NodePayload::unmarshal_binary should fail");
let mut reader = BufReader::new(&data[..]);
PeerEncodedInfo::unmarshal_binary(&mut reader)
.expect_err("PeerEncodedInfo::unmarshal_binary should fail");
Ok(())
}
}