stacks_common/deps_common/bitcoin/network/
message_blockdata.rsuse crate::deps_common::bitcoin::network::constants;
use crate::deps_common::bitcoin::network::encodable::{ConsensusDecodable, ConsensusEncodable};
use crate::deps_common::bitcoin::network::serialize::{self, SimpleDecoder, SimpleEncoder};
use crate::deps_common::bitcoin::util::hash::Sha256dHash;
#[derive(PartialEq, Eq, Clone, Debug)]
pub enum InvType {
Error,
Transaction,
Block,
WitnessBlock,
WitnessTransaction,
}
#[derive(PartialEq, Eq, Clone, Debug)]
pub struct GetBlocksMessage {
pub version: u32,
pub locator_hashes: Vec<Sha256dHash>,
pub stop_hash: Sha256dHash,
}
#[derive(PartialEq, Eq, Clone, Debug)]
pub struct GetHeadersMessage {
pub version: u32,
pub locator_hashes: Vec<Sha256dHash>,
pub stop_hash: Sha256dHash,
}
#[derive(PartialEq, Eq, Clone, Debug)]
pub struct Inventory {
pub inv_type: InvType,
pub hash: Sha256dHash,
}
impl GetBlocksMessage {
pub fn new(locator_hashes: Vec<Sha256dHash>, stop_hash: Sha256dHash) -> GetBlocksMessage {
GetBlocksMessage {
version: constants::PROTOCOL_VERSION,
locator_hashes,
stop_hash,
}
}
}
impl_consensus_encoding!(GetBlocksMessage, version, locator_hashes, stop_hash);
impl GetHeadersMessage {
pub fn new(locator_hashes: Vec<Sha256dHash>, stop_hash: Sha256dHash) -> GetHeadersMessage {
GetHeadersMessage {
version: constants::PROTOCOL_VERSION,
locator_hashes,
stop_hash,
}
}
}
impl_consensus_encoding!(GetHeadersMessage, version, locator_hashes, stop_hash);
impl<S: SimpleEncoder> ConsensusEncodable<S> for Inventory {
#[inline]
fn consensus_encode(&self, s: &mut S) -> Result<(), serialize::Error> {
match self.inv_type {
InvType::Error => 0u32,
InvType::Transaction => 1,
InvType::Block => 2,
InvType::WitnessBlock => 0x40000002,
InvType::WitnessTransaction => 0x40000001,
}
.consensus_encode(s)?;
self.hash.consensus_encode(s)
}
}
impl<D: SimpleDecoder> ConsensusDecodable<D> for Inventory {
#[inline]
fn consensus_decode(d: &mut D) -> Result<Inventory, serialize::Error> {
let int_type: u32 = ConsensusDecodable::consensus_decode(d)?;
Ok(Inventory {
inv_type: match int_type {
0 => InvType::Error,
1 => InvType::Transaction,
2 => InvType::Block,
_ => panic!("bad inventory type field"),
},
hash: ConsensusDecodable::consensus_decode(d)?,
})
}
}
#[cfg(test)]
mod tests {
use super::{GetBlocksMessage, GetHeadersMessage};
use crate::deps_common::bitcoin::network::serialize::{deserialize, serialize};
use crate::util::hash::hex_bytes as hex_decode;
#[test]
fn getblocks_message_test() {
let from_sat = hex_decode("72110100014a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b0000000000000000000000000000000000000000000000000000000000000000").unwrap();
let genhash =
hex_decode("4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b").unwrap();
let decode: Result<GetBlocksMessage, _> = deserialize(&from_sat);
assert!(decode.is_ok());
let real_decode = decode.unwrap();
assert_eq!(real_decode.version, 70002);
assert_eq!(real_decode.locator_hashes.len(), 1);
assert_eq!(
serialize(&real_decode.locator_hashes[0]).ok(),
Some(genhash)
);
assert_eq!(real_decode.stop_hash, Default::default());
assert_eq!(serialize(&real_decode).ok(), Some(from_sat));
}
#[test]
fn getheaders_message_test() {
let from_sat = hex_decode("72110100014a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b0000000000000000000000000000000000000000000000000000000000000000").unwrap();
let genhash =
hex_decode("4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b").unwrap();
let decode: Result<GetHeadersMessage, _> = deserialize(&from_sat);
assert!(decode.is_ok());
let real_decode = decode.unwrap();
assert_eq!(real_decode.version, 70002);
assert_eq!(real_decode.locator_hashes.len(), 1);
assert_eq!(
serialize(&real_decode.locator_hashes[0]).ok(),
Some(genhash)
);
assert_eq!(real_decode.stop_hash, Default::default());
assert_eq!(serialize(&real_decode).ok(), Some(from_sat));
}
}