use std::{
convert::TryInto,
fmt,
io::{self, Read, Write},
net::{Ipv4Addr, SocketAddrV4},
};
use rand::random;
use serde::{Deserialize, Serialize};
use crate::{
__impl_index,
config::Config,
hash::double_sha512,
io::{LenBm, LimitedReadFrom, ReadFrom, SizedReadFrom, WriteTo},
net::SocketAddr,
object,
packet::{self, Command, Packet},
pow,
priv_util::ToHexString,
time::Time,
var_type::{VarInt, VarStr},
};
pub use crate::{
io::TooLongError,
net_addr::{NetAddr, Services},
stream::{StreamNumber, StreamNumbers},
};
pub trait Message {
const COMMAND: Command;
}
pub trait Pack {
fn pack(&self, config: &Config) -> packet::Result<Packet>;
}
impl<T> Pack for T
where
T: WriteTo + Message,
{
fn pack(&self, config: &Config) -> packet::Result<Packet> {
let mut bytes = Vec::new();
self.write_to(&mut bytes).unwrap();
Packet::new(config, Self::COMMAND, bytes)
}
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub struct Fatal(VarInt);
impl fmt::Display for Fatal {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
}
impl Fatal {
pub fn new(value: u64) -> Self {
Self(value.into())
}
pub fn as_u64(self) -> u64 {
self.0.as_u64()
}
}
impl From<u64> for Fatal {
fn from(value: u64) -> Self {
Self(value.into())
}
}
impl WriteTo for Fatal {
fn write_to(&self, w: &mut dyn Write) -> io::Result<()> {
self.0.write_to(w)
}
}
impl ReadFrom for Fatal {
fn read_from(r: &mut dyn Read) -> io::Result<Self>
where
Self: Sized,
{
Ok(Self(VarInt::read_from(r)?))
}
}
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub struct ErrorText(VarStr);
impl ErrorText {
pub fn new(bytes: Vec<u8>) -> Self {
Self(VarStr::new(bytes))
}
}
impl fmt::Display for ErrorText {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
}
impl From<Vec<u8>> for ErrorText {
fn from(bytes: Vec<u8>) -> Self {
Self(bytes.into())
}
}
impl WriteTo for ErrorText {
fn write_to(&self, w: &mut dyn Write) -> io::Result<()> {
self.0.write_to(w)
}
}
impl LimitedReadFrom for ErrorText {
fn limited_read_from(r: &mut dyn Read, max_len: usize) -> io::Result<Self>
where
Self: Sized,
{
Ok(Self(VarStr::limited_read_from(r, max_len)?))
}
}
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub struct Error {
fatal: Fatal,
ban_time: VarInt,
inventory_vector: VarStr,
error_text: ErrorText,
}
impl Error {
pub fn new(fatal: Fatal, error_text: ErrorText) -> Self {
Self {
fatal,
ban_time: 0u64.into(),
inventory_vector: b"".to_vec().into(),
error_text,
}
}
pub fn fatal(&self) -> Fatal {
self.fatal
}
pub fn error_text(&self) -> &ErrorText {
&self.error_text
}
}
impl WriteTo for Error {
fn write_to(&self, w: &mut dyn Write) -> io::Result<()> {
self.fatal.write_to(w)?;
self.ban_time.write_to(w)?;
self.inventory_vector.write_to(w)?;
self.error_text.write_to(w)?;
Ok(())
}
}
impl ReadFrom for Error {
fn read_from(r: &mut dyn Read) -> io::Result<Self>
where
Self: Sized,
{
const MAX_VAR_STR_LENGTH: usize = 5000;
Ok(Self {
fatal: Fatal::read_from(r)?,
ban_time: VarInt::read_from(r)?,
inventory_vector: VarStr::limited_read_from(r, MAX_VAR_STR_LENGTH)?,
error_text: ErrorText::limited_read_from(r, MAX_VAR_STR_LENGTH)?,
})
}
}
impl Message for Error {
const COMMAND: Command = Command::ERROR;
}
#[test]
fn test_error_write_to() {
let test = Error::new(1u64.into(), b"hello".to_vec().into());
let mut bytes = Vec::new();
test.write_to(&mut bytes).unwrap();
let expected = [1, 0, 0, 5, b'h', b'e', b'l', b'l', b'o'];
assert_eq!(bytes, expected.to_vec());
}
#[test]
fn test_error_read_from() {
use std::io::Cursor;
let mut bytes = Cursor::new([1, 0, 0, 5, b'h', b'e', b'l', b'l', b'o']);
let test = Error::read_from(&mut bytes).unwrap();
let expected = Error::new(1u64.into(), b"hello".to_vec().into());
assert_eq!(test, expected);
}
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub struct InvHash([u8; 32]);
impl InvHash {
pub fn new(value: [u8; 32]) -> Self {
Self(value)
}
}
impl fmt::Display for InvHash {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.to_hex_string().fmt(f)
}
}
impl AsRef<[u8]> for InvHash {
fn as_ref(&self) -> &[u8] {
&self.0
}
}
impl WriteTo for InvHash {
fn write_to(&self, w: &mut dyn Write) -> io::Result<()> {
self.0.write_to(w)
}
}
impl ReadFrom for InvHash {
fn read_from(r: &mut dyn Read) -> io::Result<Self>
where
Self: Sized,
{
Ok(Self(<[u8; 32]>::read_from(r)?))
}
}
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub struct Getdata {
list: Vec<InvHash>,
}
impl AsRef<[InvHash]> for Getdata {
fn as_ref(&self) -> &[InvHash] {
&self.list
}
}
__impl_index!(Getdata, list, InvHash);
impl Getdata {
pub const MAX_COUNT: usize = 50000;
pub fn new(list: Vec<InvHash>) -> Result<Self, TooLongError> {
if list.len() > Self::MAX_COUNT {
return Err(TooLongError::new(Self::MAX_COUNT, list.len()));
}
Ok(Self { list })
}
}
impl WriteTo for Getdata {
fn write_to(&self, w: &mut dyn Write) -> io::Result<()> {
let count: VarInt = self.list.len().into();
count.write_to(w)?;
for a in &self.list {
a.write_to(w)?
}
Ok(())
}
}
impl ReadFrom for Getdata {
fn read_from(r: &mut dyn Read) -> io::Result<Self>
where
Self: Sized,
{
let count = VarInt::read_from(r)?;
if count.as_u64() > Self::MAX_COUNT as u64 {
return Err(io::Error::new(
io::ErrorKind::Other,
TooLongError::new(Self::MAX_COUNT, count.as_u64() as usize),
));
}
let mut list = Vec::<InvHash>::new();
for _ in 0..count.as_u64() {
list.push(InvHash::read_from(r)?);
}
Ok(Self { list })
}
}
impl Message for Getdata {
const COMMAND: Command = Command::GETDATA;
}
#[test]
fn test_getdata_write_to() {
let inv0 = InvHash::new([0x01; 32]);
let inv1 = InvHash::new([0x23; 32]);
let inv2 = InvHash::new([0x45; 32]);
let test = Getdata::new([inv0, inv1, inv2].to_vec()).unwrap();
let mut bytes = Vec::new();
test.write_to(&mut bytes).unwrap();
let expected = [
3,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01,
0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
0x23, 0x23,
0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45,
0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45,
0x45, 0x45,
];
assert_eq!(bytes, expected.to_vec());
}
#[test]
fn test_getdata_read_from() {
use std::io::Cursor;
let mut bytes = Cursor::new(
[
3,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01,
0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
0x23, 0x23, 0x23, 0x23,
0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45,
0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45,
0x45, 0x45, 0x45, 0x45,
]
.to_vec(),
);
let test = Getdata::read_from(&mut bytes).unwrap();
let inv0 = InvHash::new([0x01; 32]);
let inv1 = InvHash::new([0x23; 32]);
let inv2 = InvHash::new([0x45; 32]);
let expected = Getdata::new([inv0, inv1, inv2].to_vec()).unwrap();
assert_eq!(test, expected);
}
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub struct Inv {
list: Vec<InvHash>,
}
impl AsRef<[InvHash]> for Inv {
fn as_ref(&self) -> &[InvHash] {
&self.list
}
}
__impl_index!(Inv, list, InvHash);
impl Inv {
const MAX_COUNT: usize = 50000;
pub const MAX_COUNT_FIXED: usize = Self::MAX_COUNT - 1;
pub fn new(list: Vec<InvHash>) -> Result<Self, TooLongError> {
if list.len() > Self::MAX_COUNT_FIXED {
return Err(TooLongError::new(Self::MAX_COUNT_FIXED, list.len()));
}
Ok(Self { list })
}
}
impl WriteTo for Inv {
fn write_to(&self, w: &mut dyn Write) -> io::Result<()> {
let count: VarInt = self.list.len().into();
count.write_to(w)?;
for a in &self.list {
a.write_to(w)?
}
Ok(())
}
}
impl ReadFrom for Inv {
fn read_from(r: &mut dyn Read) -> io::Result<Self>
where
Self: Sized,
{
let count = VarInt::read_from(r)?;
if count.as_u64() > Self::MAX_COUNT as u64 {
return Err(io::Error::new(
io::ErrorKind::Other,
TooLongError::new(Self::MAX_COUNT, count.as_u64() as usize),
));
}
let mut list = Vec::<InvHash>::new();
for _ in 0..count.as_u64() {
list.push(InvHash::read_from(r)?);
}
Ok(Self { list })
}
}
impl Message for Inv {
const COMMAND: Command = Command::INV;
}
#[test]
fn test_inv_write_to() {
let inv0 = InvHash::new([0x01; 32]);
let inv1 = InvHash::new([0x23; 32]);
let inv2 = InvHash::new([0x45; 32]);
let test = Inv::new([inv0, inv1, inv2].to_vec()).unwrap();
let mut bytes = Vec::new();
test.write_to(&mut bytes).unwrap();
let expected = [
3,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01,
0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
0x23, 0x23,
0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45,
0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45,
0x45, 0x45,
];
assert_eq!(bytes, expected.to_vec());
}
#[test]
fn test_inv_read_from() {
use std::io::Cursor;
let mut bytes = Cursor::new(
[
3,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01,
0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
0x23, 0x23, 0x23, 0x23,
0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45,
0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45,
0x45, 0x45, 0x45, 0x45,
]
.to_vec(),
);
let test = Inv::read_from(&mut bytes).unwrap();
let inv0 = InvHash::new([0x01; 32]);
let inv1 = InvHash::new([0x23; 32]);
let inv2 = InvHash::new([0x45; 32]);
let expected = Inv::new([inv0, inv1, inv2].to_vec()).unwrap();
assert_eq!(test, expected);
}
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub struct Object {
nonce: pow::Nonce,
header: object::Header,
object_payload: Vec<u8>,
}
impl Object {
pub const MAX_OBJECT_PAYLOAD_LENGTH: usize = 1 << 18;
pub fn new(
nonce: pow::Nonce,
header: object::Header,
object_payload: Vec<u8>,
) -> Result<Self, TooLongError> {
if object_payload.len() > Self::MAX_OBJECT_PAYLOAD_LENGTH {
return Err(TooLongError::new(
Self::MAX_OBJECT_PAYLOAD_LENGTH,
object_payload.len(),
));
}
Ok(Self {
nonce,
header,
object_payload,
})
}
pub fn nonce(&self) -> pow::Nonce {
self.nonce
}
pub fn header(&self) -> &object::Header {
&self.header
}
pub fn object_payload(&self) -> &[u8] {
&self.object_payload
}
pub fn inv_hash(&self) -> InvHash {
let mut bytes: Vec<u8> = Vec::new();
self.write_to(&mut bytes).unwrap();
InvHash(double_sha512(bytes)[0..32].try_into().unwrap())
}
pub fn validate_pow_custom(
&self,
config: &Config,
nonce_trials_per_byte: pow::NonceTrialsPerByte,
extra_bytes: pow::PayloadLengthExtraBytes,
now: Time,
) -> Result<(), pow::ValidateError> {
let mut bytes =
Vec::with_capacity(self.header.len_bm() as usize + self.object_payload.len());
self.header.write_to(&mut bytes).unwrap();
self.object_payload.write_to(&mut bytes).unwrap();
let initial_hash = pow::initial_hash(&bytes);
let target = pow::target(
config,
bytes.len(),
self.header.expires_time(),
now,
nonce_trials_per_byte,
extra_bytes,
);
pow::validate(initial_hash, target, self.nonce)
}
pub fn validate_pow(&self, config: &Config) -> Result<(), pow::ValidateError> {
self.validate_pow_custom(
config,
config.nonce_trials_per_byte(),
config.payload_length_extra_bytes(),
Time::now(),
)
}
}
impl WriteTo for Object {
fn write_to(&self, w: &mut dyn Write) -> io::Result<()> {
self.nonce.write_to(w)?;
self.header.write_to(w)?;
self.object_payload.write_to(w)?;
Ok(())
}
}
impl SizedReadFrom for Object {
fn sized_read_from(r: &mut dyn Read, len: usize) -> io::Result<Self>
where
Self: Sized,
{
let nonce = pow::Nonce::read_from(r)?;
let header = object::Header::read_from(r)?;
let object_payload_len = len - nonce.len_bm() - header.len_bm();
if object_payload_len > Self::MAX_OBJECT_PAYLOAD_LENGTH {
return Err(io::Error::new(
io::ErrorKind::Other,
TooLongError::new(Self::MAX_OBJECT_PAYLOAD_LENGTH, object_payload_len),
));
}
let object_payload = Vec::<u8>::sized_read_from(r, object_payload_len)?;
Ok(Self {
nonce,
header,
object_payload,
})
}
}
impl Message for Object {
const COMMAND: Command = Command::OBJECT;
}
#[test]
fn test_object_write_to() {
let nonce = pow::Nonce::new(0xfedc_ba98_7654_3210);
let header = object::Header::new(
0x0123_4567_89ab_cdef.into(),
2.into(),
3u64.into(),
1u32.into(),
);
let object_payload = [0xff; 23].to_vec();
let test = Object::new(nonce, header, object_payload).unwrap();
let mut bytes = Vec::new();
test.write_to(&mut bytes).unwrap();
let expected = [
0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x00, 0x00, 0x00, 0x02, 3, 1,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
];
assert_eq!(bytes, expected.to_vec());
}
#[test]
fn test_object_sized_read_from() {
use std::io::Cursor;
let mut bytes = Cursor::new(
[
0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x00, 0x00, 0x00, 0x02, 3, 1,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
]
.to_vec(),
);
let test = Object::sized_read_from(&mut bytes, 45).unwrap();
let nonce = pow::Nonce::new(0xfedc_ba98_7654_3210);
let header = object::Header::new(
0x0123_4567_89ab_cdef.into(),
2.into(),
3u64.into(),
1u32.into(),
);
let object_payload = [0xff; 23].to_vec();
let expected = Object::new(nonce, header, object_payload).unwrap();
assert_eq!(test, expected);
}
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub struct Addr {
list: Vec<NetAddr>,
}
impl AsRef<[NetAddr]> for Addr {
fn as_ref(&self) -> &[NetAddr] {
&self.list
}
}
__impl_index!(Addr, list, NetAddr);
impl Addr {
pub const MAX_COUNT: usize = 1000;
pub fn new(list: Vec<NetAddr>) -> Result<Self, TooLongError> {
if list.len() > Self::MAX_COUNT {
return Err(TooLongError::new(Self::MAX_COUNT, list.len()));
}
Ok(Self { list })
}
}
impl WriteTo for Addr {
fn write_to(&self, w: &mut dyn Write) -> io::Result<()> {
let count: VarInt = self.list.len().into();
count.write_to(w)?;
for a in &self.list {
a.write_to(w)?
}
Ok(())
}
}
impl ReadFrom for Addr {
fn read_from(r: &mut dyn Read) -> io::Result<Self>
where
Self: Sized,
{
let count = VarInt::read_from(r)?;
if count.as_u64() > Self::MAX_COUNT as u64 {
return Err(io::Error::new(
io::ErrorKind::Other,
TooLongError::new(Self::MAX_COUNT, count.as_u64() as usize),
));
}
let mut list = Vec::<NetAddr>::new();
for _ in 0..count.as_u64() {
list.push(NetAddr::read_from(r)?);
}
Ok(Self { list })
}
}
impl Message for Addr {
const COMMAND: Command = Command::ADDR;
}
#[test]
fn test_addr_write_to() {
let addr0 = NetAddr::new(
0x0123_4567_89ab_cdef.into(),
1.into(),
Services::NETWORK,
LOCAL_SOCKET_ADDR.clone(),
);
let addr1 = NetAddr::new(
0x0123_4567_89ab_cdef.into(),
1.into(),
Services::NETWORK,
LOCAL_SOCKET_ADDR.clone(),
);
let addr2 = NetAddr::new(
0x0123_4567_89ab_cdef.into(),
1.into(),
Services::NETWORK,
LOCAL_SOCKET_ADDR.clone(),
);
let test = Addr::new([addr0, addr1, addr2].to_vec()).unwrap();
let mut bytes = Vec::new();
test.write_to(&mut bytes).unwrap();
let expected = [
3,
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 127, 0, 0, 1, 0x20, 0xfc,
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 127, 0, 0, 1, 0x20, 0xfc,
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 127, 0, 0, 1, 0x20, 0xfc,
];
assert_eq!(bytes, expected.to_vec());
}
#[test]
fn test_addr_read_from() {
use std::io::Cursor;
let mut bytes = Cursor::new(
[
3,
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 127, 0, 0, 1, 0x20, 0xfc,
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 127, 0, 0, 1, 0x20, 0xfc,
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 127, 0, 0, 1, 0x20, 0xfc,
]
.to_vec(),
);
let test = Addr::read_from(&mut bytes).unwrap();
let addr0 = NetAddr::new(
0x0123_4567_89ab_cdef.into(),
1.into(),
Services::NETWORK,
LOCAL_SOCKET_ADDR.clone(),
);
let addr1 = NetAddr::new(
0x0123_4567_89ab_cdef.into(),
1.into(),
Services::NETWORK,
LOCAL_SOCKET_ADDR.clone(),
);
let addr2 = NetAddr::new(
0x0123_4567_89ab_cdef.into(),
1.into(),
Services::NETWORK,
LOCAL_SOCKET_ADDR.clone(),
);
let expected = Addr::new([addr0, addr1, addr2].to_vec()).unwrap();
assert_eq!(test, expected);
}
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub struct Ping {
payload: Vec<u8>,
}
impl Default for Ping {
fn default() -> Self {
Self {
payload: Vec::with_capacity(0),
}
}
}
impl Ping {
pub fn new() -> Self {
Self::default()
}
pub fn with_payload(payload: Vec<u8>) -> Self {
Self { payload }
}
pub fn payload(&self) -> &[u8] {
&self.payload
}
}
impl WriteTo for Ping {
fn write_to(&self, w: &mut dyn Write) -> io::Result<()> {
self.payload.write_to(w)?;
Ok(())
}
}
impl SizedReadFrom for Ping {
fn sized_read_from(r: &mut dyn Read, len: usize) -> io::Result<Self>
where
Self: Sized,
{
Ok(Self {
payload: Vec::<u8>::sized_read_from(r, len)?,
})
}
}
impl Message for Ping {
const COMMAND: Command = Command::PING;
}
#[test]
fn test_ping_write_to() {
let test = Ping::with_payload(b"hello".to_vec());
let mut bytes = Vec::new();
test.write_to(&mut bytes).unwrap();
let expected = [b'h', b'e', b'l', b'l', b'o'];
assert_eq!(bytes, expected.to_vec());
}
#[test]
fn test_ping_sized_read_from() {
use std::io::Cursor;
let mut bytes = Cursor::new([b'h', b'e', b'l', b'l', b'o']);
let test = Ping::sized_read_from(&mut bytes, 5).unwrap();
let expected = Ping::with_payload(b"hello".to_vec());
assert_eq!(test, expected);
}
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub struct Pong {
payload: Vec<u8>,
}
impl Default for Pong {
fn default() -> Self {
Self {
payload: Vec::with_capacity(0),
}
}
}
impl Pong {
pub fn new() -> Self {
Self::default()
}
pub fn with_payload(payload: Vec<u8>) -> Self {
Self { payload }
}
pub fn payload(&self) -> &[u8] {
&self.payload
}
}
impl WriteTo for Pong {
fn write_to(&self, w: &mut dyn Write) -> io::Result<()> {
self.payload.write_to(w)?;
Ok(())
}
}
impl SizedReadFrom for Pong {
fn sized_read_from(r: &mut dyn Read, len: usize) -> io::Result<Self>
where
Self: Sized,
{
Ok(Self {
payload: Vec::<u8>::sized_read_from(r, len)?,
})
}
}
impl Message for Pong {
const COMMAND: Command = Command::PONG;
}
#[test]
fn test_pong_write_to() {
let test = Pong::with_payload(b"hello".to_vec());
let mut bytes = Vec::new();
test.write_to(&mut bytes).unwrap();
let expected = [b'h', b'e', b'l', b'l', b'o'];
assert_eq!(bytes, expected.to_vec());
}
#[test]
fn test_pong_sized_read_from() {
use std::io::Cursor;
let mut bytes = Cursor::new([b'h', b'e', b'l', b'l', b'o']);
let test = Pong::sized_read_from(&mut bytes, 5).unwrap();
let expected = Pong::with_payload(b"hello".to_vec());
assert_eq!(test, expected);
}
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub struct Verack {}
impl Default for Verack {
fn default() -> Self {
Self {}
}
}
impl Verack {
pub fn new() -> Self {
Self::default()
}
}
impl WriteTo for Verack {
fn write_to(&self, _w: &mut dyn Write) -> io::Result<()> {
Ok(())
}
}
impl ReadFrom for Verack {
fn read_from(_r: &mut dyn Read) -> io::Result<Self>
where
Self: Sized,
{
Ok(Self {})
}
}
impl Message for Verack {
const COMMAND: Command = Command::VERACK;
}
#[test]
fn test_verack_write_to() {
let test = Verack::new();
let mut bytes = Vec::new();
test.write_to(&mut bytes).unwrap();
let expected = [];
assert_eq!(bytes, expected.to_vec());
}
#[test]
fn test_verack_read_from() {
use std::io::Cursor;
let mut bytes = Cursor::new([]);
let test = Verack::read_from(&mut bytes).unwrap();
let expected = Verack::new();
assert_eq!(test, expected);
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Serialize, Deserialize)]
pub struct ProtocolVersion(u32);
impl ProtocolVersion {
pub fn new(value: u32) -> Self {
Self(value)
}
pub fn as_u32(self) -> u32 {
self.0
}
}
impl fmt::Display for ProtocolVersion {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
}
impl From<u32> for ProtocolVersion {
fn from(value: u32) -> Self {
Self(value)
}
}
impl WriteTo for ProtocolVersion {
fn write_to(&self, w: &mut dyn Write) -> io::Result<()> {
self.0.write_to(w)
}
}
impl ReadFrom for ProtocolVersion {
fn read_from(r: &mut dyn Read) -> io::Result<Self>
where
Self: Sized,
{
Ok(Self(u32::read_from(r)?))
}
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub struct NodeNonce(u64);
impl NodeNonce {
pub fn new(value: u64) -> Self {
Self(value)
}
pub fn random() -> Self {
Self(random::<u64>())
}
pub fn as_u64(self) -> u64 {
self.0
}
}
impl fmt::Display for NodeNonce {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:016x}", self.0)
}
}
impl From<u64> for NodeNonce {
fn from(value: u64) -> Self {
Self(value)
}
}
impl WriteTo for NodeNonce {
fn write_to(&self, w: &mut dyn Write) -> io::Result<()> {
self.0.write_to(w)
}
}
impl ReadFrom for NodeNonce {
fn read_from(r: &mut dyn Read) -> io::Result<Self>
where
Self: Sized,
{
Ok(Self(u64::read_from(r)?))
}
}
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Serialize, Deserialize)]
pub struct UserAgent(VarStr);
impl UserAgent {
pub fn new(bytes: Vec<u8>) -> Self {
Self(VarStr::new(bytes))
}
}
impl fmt::Display for UserAgent {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
}
impl From<Vec<u8>> for UserAgent {
fn from(bytes: Vec<u8>) -> Self {
Self(bytes.into())
}
}
impl WriteTo for UserAgent {
fn write_to(&self, w: &mut dyn Write) -> io::Result<()> {
self.0.write_to(w)
}
}
impl LimitedReadFrom for UserAgent {
fn limited_read_from(r: &mut dyn Read, max_len: usize) -> io::Result<Self>
where
Self: Sized,
{
Ok(Self(VarStr::limited_read_from(r, max_len)?))
}
}
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub struct Version {
version: ProtocolVersion,
services: Services,
timestamp: Time,
remote_services: Services,
addr_recv: SocketAddr,
services2: Services,
addr_from: SocketAddr,
nonce: NodeNonce,
user_agent: UserAgent,
stream_numbers: StreamNumbers,
}
lazy_static! {
static ref LOCAL_SOCKET_ADDR: SocketAddr =
SocketAddr::Ipv4(SocketAddrV4::new(Ipv4Addr::LOCALHOST, 8444));
}
impl Version {
const MAX_USER_AGENT_LENGTH: usize = 5000 - 3;
pub fn builder(config: &Config, nonce: NodeNonce, user_agent: UserAgent) -> VersionBuilder {
VersionBuilder::new(config, nonce, user_agent)
}
pub fn version(&self) -> ProtocolVersion {
self.version
}
pub fn services(&self) -> Services {
self.services
}
pub fn timestamp(&self) -> Time {
self.timestamp
}
pub fn nonce(&self) -> NodeNonce {
self.nonce
}
pub fn user_agent(&self) -> &UserAgent {
&self.user_agent
}
pub fn stream_numbers(&self) -> &StreamNumbers {
&self.stream_numbers
}
}
impl WriteTo for Version {
fn write_to(&self, w: &mut dyn Write) -> io::Result<()> {
self.version.write_to(w)?;
self.services.write_to(w)?;
self.timestamp.write_to(w)?;
self.remote_services.write_to(w)?;
self.addr_recv.write_to(w)?;
self.services2.write_to(w)?;
self.addr_from.write_to(w)?;
self.nonce.write_to(w)?;
self.user_agent.write_to(w)?;
self.stream_numbers.write_to(w)?;
Ok(())
}
}
impl ReadFrom for Version {
fn read_from(r: &mut dyn Read) -> io::Result<Self>
where
Self: Sized,
{
Ok(Self {
version: ProtocolVersion::read_from(r)?,
services: Services::read_from(r)?,
timestamp: Time::read_from(r)?,
remote_services: Services::read_from(r)?,
addr_recv: SocketAddr::read_from(r)?,
services2: Services::read_from(r)?,
addr_from: SocketAddr::read_from(r)?,
nonce: NodeNonce::read_from(r)?,
user_agent: UserAgent::limited_read_from(r, Self::MAX_USER_AGENT_LENGTH)?,
stream_numbers: StreamNumbers::read_from(r)?,
})
}
}
impl Message for Version {
const COMMAND: Command = Command::VERSION;
}
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub struct VersionBuilder {
message: Version,
}
impl VersionBuilder {
fn new(config: &Config, nonce: NodeNonce, user_agent: UserAgent) -> Self {
let stream_numbers: StreamNumbers = vec![1_u32.into()].into();
let message = Version {
version: config.protocol_version(),
services: Services::NETWORK,
timestamp: Time::now(),
remote_services: Services::NETWORK,
addr_recv: LOCAL_SOCKET_ADDR.clone(),
services2: Services::NETWORK,
addr_from: LOCAL_SOCKET_ADDR.clone(),
nonce,
user_agent,
stream_numbers,
};
Self { message }
}
pub fn services(&mut self, services: Services) -> &mut Self {
self.message.services = services;
self
}
pub fn timestamp(&mut self, timestamp: Time) -> &mut Self {
self.message.timestamp = timestamp;
self
}
pub fn stream_numbers(&mut self, list: StreamNumbers) -> &mut Self {
self.message.stream_numbers = list;
self
}
pub fn build(&self) -> Version {
self.message.clone()
}
}
#[test]
fn test_version_write_to() {
let config = Config::new();
let stream_numbers: StreamNumbers = vec![1_u32.into(), 2_u32.into()].into();
let test = Version::builder(
&config,
0x0123_4567_89ab_cdef.into(),
b"hello".to_vec().into(),
)
.stream_numbers(stream_numbers)
.build();
let mut bytes = Vec::new();
test.write_to(&mut bytes).unwrap();
bytes[12..20].copy_from_slice(&[0xff; 8]);
let expected = [
0, 0, 0, 3,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 127, 0, 0, 1, 0x20, 0xfc,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 127, 0, 0, 1, 0x20, 0xfc,
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
5, b'h', b'e', b'l', b'l', b'o',
2, 1, 2,
];
assert_eq!(bytes, expected.to_vec());
}
#[test]
fn test_version_read_from() {
use std::io::Cursor;
let mut bytes = Cursor::new(
[
0, 0, 0, 3,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 127, 0, 0, 1, 0x20, 0xfc,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 127, 0, 0, 1, 0x20, 0xfc,
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
5, b'h', b'e', b'l', b'l', b'o',
2, 1, 2,
]
.to_vec(),
);
let test = Version::read_from(&mut bytes).unwrap();
let stream_numbers: StreamNumbers = vec![1_u32.into(), 2_u32.into()].into();
let config = Config::new();
let mut expected = Version::builder(
&config,
0x0123_4567_89ab_cdef.into(),
b"hello".to_vec().into(),
)
.stream_numbers(stream_numbers)
.build();
expected.timestamp = 0xffff_ffff_ffff_ffff.into();
assert_eq!(test, expected);
}