diff --git a/src/network/message.rs b/src/network/message.rs index f51dd9b1..6066617b 100644 --- a/src/network/message.rs +++ b/src/network/message.rs @@ -28,6 +28,7 @@ use blockdata::transaction; use network::address::Address; use network::message_network; use network::message_blockdata; +use network::message_filter; use consensus::encode::{Decodable, Encodable}; use consensus::encode::CheckedData; use consensus::encode::{self, serialize, Encoder, Decoder}; @@ -117,7 +118,18 @@ pub enum NetworkMessage { Pong(u64), // TODO: reject, // TODO: bloom filtering - // TODO: alert + /// BIP157 getcfilters + GetCFilters(message_filter::GetCFilters), + /// BIP157 cfilter + CFilter(message_filter::CFilter), + /// BIP157 getcfheaders + GetCFHeaders(message_filter::GetCFHeaders), + /// BIP157 cfheaders + CFHeaders(message_filter::CFHeaders), + /// BIP157 getcfcheckpt + GetCFCheckpt(message_filter::GetCFCheckpt), + /// BIP157 cfcheckpt + CFCheckpt(message_filter::CFCheckpt), /// `alert` Alert(Vec) } @@ -141,6 +153,12 @@ impl RawNetworkMessage { NetworkMessage::GetAddr => "getaddr", NetworkMessage::Ping(_) => "ping", NetworkMessage::Pong(_) => "pong", + NetworkMessage::GetCFilters(_) => "getcfilters", + NetworkMessage::CFilter(_) => "cfilter", + NetworkMessage::GetCFHeaders(_) => "getcfheaders", + NetworkMessage::CFHeaders(_) => "cfheaders", + NetworkMessage::GetCFCheckpt(_) => "getcfckpt", + NetworkMessage::CFCheckpt(_) => "cfcheckpt", NetworkMessage::Alert(_) => "alert", }.to_owned() } @@ -163,6 +181,12 @@ impl Encodable for RawNetworkMessage { NetworkMessage::Headers(ref dat) => serialize(dat), NetworkMessage::Ping(ref dat) => serialize(dat), NetworkMessage::Pong(ref dat) => serialize(dat), + NetworkMessage::GetCFilters(ref dat) => serialize(dat), + NetworkMessage::CFilter(ref dat) => serialize(dat), + NetworkMessage::GetCFHeaders(ref dat) => serialize(dat), + NetworkMessage::CFHeaders(ref dat) => serialize(dat), + NetworkMessage::GetCFCheckpt(ref dat) => serialize(dat), + NetworkMessage::CFCheckpt(ref dat) => serialize(dat), NetworkMessage::Alert(ref dat) => serialize(dat), NetworkMessage::Verack | NetworkMessage::MemPool @@ -194,6 +218,12 @@ impl Decodable for RawNetworkMessage { "ping" => NetworkMessage::Ping(Decodable::consensus_decode(&mut mem_d)?), "pong" => NetworkMessage::Pong(Decodable::consensus_decode(&mut mem_d)?), "tx" => NetworkMessage::Tx(Decodable::consensus_decode(&mut mem_d)?), + "getcfilters" => NetworkMessage::GetCFilters(Decodable::consensus_decode(&mut mem_d)?), + "cfilter" => NetworkMessage::CFilter(Decodable::consensus_decode(&mut mem_d)?), + "getcfheaders" => NetworkMessage::GetCFHeaders(Decodable::consensus_decode(&mut mem_d)?), + "cfheaders" => NetworkMessage::CFHeaders(Decodable::consensus_decode(&mut mem_d)?), + "getcfckpt" => NetworkMessage::GetCFCheckpt(Decodable::consensus_decode(&mut mem_d)?), + "cfcheckpt" => NetworkMessage::CFCheckpt(Decodable::consensus_decode(&mut mem_d)?), "alert" => NetworkMessage::Alert(Decodable::consensus_decode(&mut mem_d)?), _ => return Err(encode::Error::UnrecognizedNetworkCommand(cmd)), }; diff --git a/src/network/message_filter.rs b/src/network/message_filter.rs new file mode 100644 index 00000000..0ada431e --- /dev/null +++ b/src/network/message_filter.rs @@ -0,0 +1,76 @@ +//! +//! BIP157 Client Side Block Filtering network messages +//! +use bitcoin_hashes::sha256d; + +#[derive(PartialEq, Eq, Clone, Debug)] +/// getcfilters message +pub struct GetCFilters { + /// Filter type for which headers are requested + pub filter_type: u8, + /// The height of the first block in the requested range + pub start_height: u32, + /// The hash of the last block in the requested range + pub stop_hash: sha256d::Hash, +} +impl_consensus_encoding!(GetCFilters, filter_type, start_height, stop_hash); + +#[derive(PartialEq, Eq, Clone, Debug)] +/// cfilter message +pub struct CFilter { + /// Byte identifying the type of filter being returned + pub filter_type: u8, + /// Block hash of the Bitcoin block for which the filter is being returned + pub block_hash: sha256d::Hash, + /// The serialized compact filter for this block + pub filter: Vec, +} +impl_consensus_encoding!(CFilter, filter_type, block_hash, filter); + +#[derive(PartialEq, Eq, Clone, Debug)] +/// getcfheaders message +pub struct GetCFHeaders { + /// Byte identifying the type of filter being returned + pub filter_type: u8, + /// The height of the first block in the requested range + pub start_height: u32, + /// The hash of the last block in the requested range + pub stop_hash: sha256d::Hash, +} +impl_consensus_encoding!(GetCFHeaders, filter_type, start_height, stop_hash); + +#[derive(PartialEq, Eq, Clone, Debug)] +/// cfheaders message +pub struct CFHeaders { + /// Filter type for which headers are requested + pub filter_type: u8, + /// The hash of the last block in the requested range + pub stop_hash: sha256d::Hash, + /// The filter header preceding the first block in the requested range + pub previous_filter: sha256d::Hash, + /// The filter hashes for each block in the requested range + pub filter_hashes: Vec, +} +impl_consensus_encoding!(CFHeaders, filter_type, stop_hash, previous_filter, filter_hashes); + +#[derive(PartialEq, Eq, Clone, Debug)] +/// getcfcheckpt message +pub struct GetCFCheckpt { + /// Filter type for which headers are requested + pub filter_type: u8, + /// The hash of the last block in the requested range + pub stop_hash: sha256d::Hash, +} +impl_consensus_encoding!(GetCFCheckpt, filter_type, stop_hash); + +#[derive(PartialEq, Eq, Clone, Debug)] +/// cfcheckpt message +pub struct CFCheckpt { + /// Filter type for which headers are requested + pub filter_type: u8, + /// The hash of the last block in the requested range + pub stop_hash: sha256d::Hash, + /// The filter headers at intervals of 1,000 + pub filter_headers: Vec, +} +impl_consensus_encoding!(CFCheckpt, filter_type, stop_hash, filter_headers); \ No newline at end of file diff --git a/src/network/mod.rs b/src/network/mod.rs index 6167f342..21aaeaba 100644 --- a/src/network/mod.rs +++ b/src/network/mod.rs @@ -28,6 +28,7 @@ pub mod address; pub mod message; pub mod message_blockdata; pub mod message_network; +pub mod message_filter; /// Network error #[derive(Debug)]