few more message types
This commit is contained in:
parent
e8de78bc0b
commit
4d71c801f3
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -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); },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -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>,
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue