few more message types

This commit is contained in:
debris 2016-10-04 00:47:18 +02:00
parent e8de78bc0b
commit 4d71c801f3
10 changed files with 295 additions and 15 deletions

View File

@ -6,6 +6,7 @@ extern crate serialization as ser;
mod block;
mod block_header;
mod merkle_root;
mod merkle_block;
mod transaction;
pub use rustc_serialize::hex;
@ -13,6 +14,8 @@ pub use primitives::{hash, bytes};
pub use self::block::Block;
pub use self::block_header::BlockHeader;
pub use self::merkle_root::merkle_root;
pub use self::merkle_block::MerkleBlock;
pub use self::transaction::{
Transaction, TransactionInput, TransactionOutput, OutPoint,
SEQUENCE_LOCKTIME_DISABLE_FLAG, SEQUENCE_FINAL,

35
chain/src/merkle_block.rs Normal file
View File

@ -0,0 +1,35 @@
use hash::H256;
use bytes::Bytes;
use ser::{Serializable, Stream, Deserializable, Reader, Error as ReaderError};
use BlockHeader;
#[derive(Debug, PartialEq)]
pub struct MerkleBlock {
block_header: BlockHeader,
total_transactions: u32,
hashes: Vec<H256>,
flags: Bytes,
}
impl Serializable for MerkleBlock {
fn serialize(&self, stream: &mut Stream) {
stream
.append(&self.block_header)
.append(&self.total_transactions)
.append_list(&self.hashes)
.append(&self.flags);
}
}
impl Deserializable for MerkleBlock {
fn deserialize(reader: &mut Reader) -> Result<Self, ReaderError> where Self: Sized {
let merkle_block = MerkleBlock {
block_header: try!(reader.read()),
total_transactions: try!(reader.read()),
hashes: try!(reader.read_list()),
flags: try!(reader.read()),
};
Ok(merkle_block)
}
}

View File

@ -1,30 +1,42 @@
use ser::{
Serializable, Stream,
Reader, Error as ReaderError
Error as ReaderError, deserialize
};
use chain::{Transaction, Block};
use chain::{Transaction, Block, MerkleBlock};
use common::Command;
use types::{
Version, Addr, AddrBelow31402, Inv,
GetData, NotFound, GetBlocks, GetHeaders
GetData, NotFound, GetBlocks, GetHeaders, Headers,
Ping, Pong, Reject, FilterLoad, FilterAdd, FeeFilter,
};
pub fn deserialize_payload(data: &[u8], version: u32, command: &Command) -> Result<Payload, ReaderError> {
let mut reader = Reader::new(data);
match &command.to_string() as &str {
"version" => reader.read().map(Payload::Version),
"verack" => Ok(Payload::Verack),
"version" => deserialize(data).map(Payload::Version),
"verack" if data.is_empty() => Ok(Payload::Verack),
"addr" => match version >= 31402 {
true => reader.read().map(Payload::Addr),
false => reader.read().map(Payload::AddrBelow31402),
true => deserialize(data).map(Payload::Addr),
false => deserialize(data).map(Payload::AddrBelow31402),
},
"inv" => reader.read().map(Payload::Inv),
"getdata" => reader.read().map(Payload::GetData),
"notfound" => reader.read().map(Payload::NotFound),
"getblocks" => reader.read().map(Payload::GetBlocks),
"getheaders" => reader.read().map(Payload::GetHeaders),
"tx" => reader.read().map(Payload::Tx),
"block" => reader.read().map(Payload::Block),
"inv" => deserialize(data).map(Payload::Inv),
"getdata" => deserialize(data).map(Payload::GetData),
"notfound" => deserialize(data).map(Payload::NotFound),
"getblocks" => deserialize(data).map(Payload::GetBlocks),
"getheaders" => deserialize(data).map(Payload::GetHeaders),
"tx" => deserialize(data).map(Payload::Tx),
"block" => deserialize(data).map(Payload::Block),
"headers" => deserialize(data).map(Payload::Headers),
"getaddr" if data.is_empty() => Ok(Payload::GetAddr),
"mempool" if data.is_empty() => Ok(Payload::MemPool),
"ping" => deserialize(data).map(Payload::Ping),
"pong" => deserialize(data).map(Payload::Pong),
"reject" => deserialize(data).map(Payload::Reject),
"filterload" => deserialize(data).map(Payload::FilterLoad),
"filteradd" => deserialize(data).map(Payload::FilterAdd),
"filterclear" if data.is_empty() => Ok(Payload::FilterClear),
"merkleblock" => deserialize(data).map(Payload::MerkleBlock),
"sendheaders" if data.is_empty() => Ok(Payload::SendHeaders),
"feefilter" => deserialize(data).map(Payload::FeeFilter),
_ => Err(ReaderError::MalformedData),
}
}
@ -42,6 +54,18 @@ pub enum Payload {
GetHeaders(GetHeaders),
Tx(Transaction),
Block(Block),
Headers(Headers),
GetAddr,
MemPool,
Ping(Ping),
Pong(Pong),
Reject(Reject),
FilterLoad(FilterLoad),
FilterAdd(FilterAdd),
FilterClear,
MerkleBlock(MerkleBlock),
SendHeaders,
FeeFilter(FeeFilter),
}
impl Payload {
@ -57,6 +81,18 @@ impl Payload {
Payload::GetHeaders(_) => "getheaders",
Payload::Tx(_) => "tx",
Payload::Block(_) => "block",
Payload::Headers(_) => "headers",
Payload::GetAddr => "getaddr",
Payload::MemPool=> "mempool",
Payload::Ping(_) => "ping",
Payload::Pong(_) => "pong",
Payload::Reject(_) => "reject",
Payload::FilterLoad(_) => "filterload",
Payload::FilterAdd(_) => "filteradd",
Payload::FilterClear => "filterclear",
Payload::MerkleBlock(_) => "merkleblock",
Payload::SendHeaders => "sendheaders",
Payload::FeeFilter(_) => "feefilter",
};
cmd.into()
@ -78,6 +114,18 @@ impl Serializable for Payload {
Payload::GetHeaders(ref p) => { stream.append(p); },
Payload::Tx(ref p) => { stream.append(p); },
Payload::Block(ref p) => { stream.append(p); },
Payload::Headers(ref p) => { stream.append(p); },
Payload::GetAddr => {},
Payload::MemPool => {},
Payload::Ping(ref p) => { stream.append(p); },
Payload::Pong(ref p) => { stream.append(p); },
Payload::Reject(ref p) => { stream.append(p); },
Payload::FilterLoad(ref p) => { stream.append(p); },
Payload::FilterAdd(ref p) => { stream.append(p); },
Payload::FilterClear => {},
Payload::MerkleBlock(ref p) => { stream.append(p); },
Payload::SendHeaders => {},
Payload::FeeFilter(ref p) => { stream.append(p); },
}
}
}

View File

@ -0,0 +1,22 @@
use ser::{Serializable, Stream, Deserializable, Reader, Error as ReaderError};
#[derive(Debug, PartialEq)]
pub struct FeeFilter {
fee_rate: u64,
}
impl Serializable for FeeFilter {
fn serialize(&self, stream: &mut Stream) {
stream.append(&self.fee_rate);
}
}
impl Deserializable for FeeFilter {
fn deserialize(reader: &mut Reader) -> Result<Self, ReaderError> where Self: Sized {
let fee_filter = FeeFilter {
fee_rate: try!(reader.read()),
};
Ok(fee_filter)
}
}

View File

@ -0,0 +1,24 @@
use bytes::Bytes;
use ser::{Serializable, Stream, Deserializable, Reader, Error as ReaderError};
#[derive(Debug, PartialEq)]
pub struct FilterAdd {
// TODO: check how this should be serialized
data: Bytes,
}
impl Serializable for FilterAdd {
fn serialize(&self, stream: &mut Stream) {
stream.append(&self.data);
}
}
impl Deserializable for FilterAdd {
fn deserialize(reader: &mut Reader) -> Result<Self, ReaderError> where Self: Sized {
let filteradd= FilterAdd {
data: try!(reader.read()),
};
Ok(filteradd)
}
}

View File

@ -0,0 +1,34 @@
use bytes::Bytes;
use ser::{Serializable, Stream, Deserializable, Reader, Error as ReaderError};
#[derive(Debug, PartialEq)]
pub struct FilterLoad {
// TODO: check how this should be serialized
filter: Bytes,
hash_functions: u32,
tweak: u32,
flags: u8,
}
impl Serializable for FilterLoad {
fn serialize(&self, stream: &mut Stream) {
stream
.append(&self.filter)
.append(&self.hash_functions)
.append(&self.tweak)
.append(&self.flags);
}
}
impl Deserializable for FilterLoad {
fn deserialize(reader: &mut Reader) -> Result<Self, ReaderError> where Self: Sized {
let filterload = FilterLoad {
filter: try!(reader.read()),
hash_functions: try!(reader.read()),
tweak: try!(reader.read()),
flags: try!(reader.read()),
};
Ok(filterload)
}
}

View File

@ -1,6 +1,7 @@
use chain::BlockHeader;
use ser::{Serializable, Stream, Deserializable, Reader, Error as ReaderError};
#[derive(Debug, PartialEq)]
pub struct Headers {
headers: Vec<BlockHeader>,
}

View File

@ -1,15 +1,26 @@
mod addr;
mod feefilter;
mod filterload;
mod filteradd;
mod getblocks;
mod headers;
mod inv;
mod ping;
pub mod reject;
pub mod version;
pub use self::addr::{Addr, AddrBelow31402};
pub use self::feefilter::FeeFilter;
pub use self::filterload::FilterLoad;
pub use self::filteradd::FilterAdd;
pub use self::getblocks::GetBlocks;
pub use self::headers::Headers;
pub use self::inv::Inv;
pub use self::ping::Ping;
pub use self::reject::Reject;
pub use self::version::Version;
pub type GetData = Inv;
pub type NotFound = Inv;
pub type GetHeaders = GetBlocks;
pub type Pong = Ping;

22
message/src/types/ping.rs Normal file
View File

@ -0,0 +1,22 @@
use ser::{Serializable, Stream, Deserializable, Reader, Error as ReaderError};
#[derive(Debug, PartialEq)]
pub struct Ping {
nonce: u64,
}
impl Serializable for Ping {
fn serialize(&self, stream: &mut Stream) {
stream.append(&self.nonce);
}
}
impl Deserializable for Ping {
fn deserialize(reader: &mut Reader) -> Result<Self, ReaderError> where Self: Sized {
let ping = Ping {
nonce: try!(reader.read()),
};
Ok(ping)
}
}

View File

@ -0,0 +1,80 @@
use ser::{Serializable, Stream, Deserializable, Reader, Error as ReaderError};
#[derive(Debug, PartialEq, Clone, Copy)]
#[repr(u8)]
enum RejectCode {
Malformed = 0x01,
Invalid = 0x10,
Obsolate = 0x11,
Duplicate = 0x12,
Nonstandard = 0x40,
Dust = 0x41,
InsuficientFee = 0x42,
Checkpoint = 0x43,
}
impl From<RejectCode> for u8 {
fn from(c: RejectCode) -> Self {
c as u8
}
}
impl RejectCode {
pub fn from_u8(v: u8) -> Option<Self> {
let some = match v {
0x01 => RejectCode::Malformed,
0x10 => RejectCode::Invalid,
0x11 => RejectCode::Obsolate,
0x12 => RejectCode::Duplicate,
0x40 => RejectCode::Nonstandard,
0x41 => RejectCode::Dust,
0x42 => RejectCode::InsuficientFee,
0x43 => RejectCode::Checkpoint,
_ => return None,
};
Some(some)
}
}
impl Serializable for RejectCode {
fn serialize(&self, stream: &mut Stream) {
stream.append(&u8::from(*self));
}
}
impl Deserializable for RejectCode {
fn deserialize(reader: &mut Reader) -> Result<Self, ReaderError> where Self: Sized {
let v: u8 = try!(reader.read());
RejectCode::from_u8(v).ok_or_else(|| ReaderError::MalformedData)
}
}
#[derive(Debug, PartialEq)]
pub struct Reject {
message: String,
code: RejectCode,
reason: String,
// TODO: data
}
impl Serializable for Reject {
fn serialize(&self, stream: &mut Stream) {
stream
.append(&self.message)
.append(&self.code)
.append(&self.reason);
}
}
impl Deserializable for Reject {
fn deserialize(reader: &mut Reader) -> Result<Self, ReaderError> where Self: Sized {
let reject = Reject {
message: try!(reader.read()),
code: try!(reader.read()),
reason: try!(reader.read()),
};
Ok(reject)
}
}