bitcoin/network/
message_blockdata.rs1use network::constants;
22use consensus::encode::{Decodable, Encodable};
23use consensus::encode::{self, Decoder, Encoder};
24use bitcoin_hashes::sha256d;
25
26#[derive(PartialEq, Eq, Clone, Debug)]
27pub enum InvType {
29 Error,
31 Transaction,
33 Block,
35 WitnessBlock,
37 WitnessTransaction
39}
40
41#[derive(PartialEq, Eq, Clone, Debug)]
45pub struct GetBlocksMessage {
46 pub version: u32,
48 pub locator_hashes: Vec<sha256d::Hash>,
52 pub stop_hash: sha256d::Hash,
54}
55
56#[derive(PartialEq, Eq, Clone, Debug)]
58pub struct GetHeadersMessage {
59 pub version: u32,
61 pub locator_hashes: Vec<sha256d::Hash>,
65 pub stop_hash: sha256d::Hash
67}
68
69#[derive(PartialEq, Eq, Clone, Debug)]
71pub struct Inventory {
72 pub inv_type: InvType,
74 pub hash: sha256d::Hash
76}
77
78impl GetBlocksMessage {
79 pub fn new(locator_hashes: Vec<sha256d::Hash>, stop_hash: sha256d::Hash) -> GetBlocksMessage {
81 GetBlocksMessage {
82 version: constants::PROTOCOL_VERSION,
83 locator_hashes: locator_hashes.clone(),
84 stop_hash: stop_hash
85 }
86 }
87}
88
89impl_consensus_encoding!(GetBlocksMessage, version, locator_hashes, stop_hash);
90
91impl GetHeadersMessage {
92 pub fn new(locator_hashes: Vec<sha256d::Hash>, stop_hash: sha256d::Hash) -> GetHeadersMessage {
94 GetHeadersMessage {
95 version: constants::PROTOCOL_VERSION,
96 locator_hashes: locator_hashes,
97 stop_hash: stop_hash
98 }
99 }
100}
101
102impl_consensus_encoding!(GetHeadersMessage, version, locator_hashes, stop_hash);
103
104impl<S: Encoder> Encodable<S> for Inventory {
105 #[inline]
106 fn consensus_encode(&self, s: &mut S) -> Result<(), encode::Error> {
107 match self.inv_type {
108 InvType::Error => 0u32,
109 InvType::Transaction => 1,
110 InvType::Block => 2,
111 InvType::WitnessBlock => 0x40000002,
112 InvType::WitnessTransaction => 0x40000001
113 }.consensus_encode(s)?;
114 self.hash.consensus_encode(s)
115 }
116}
117
118impl<D: Decoder> Decodable<D> for Inventory {
119 #[inline]
120 fn consensus_decode(d: &mut D) -> Result<Inventory, encode::Error> {
121 let int_type: u32 = Decodable::consensus_decode(d)?;
122 Ok(Inventory {
123 inv_type: match int_type {
124 0 => InvType::Error,
125 1 => InvType::Transaction,
126 2 => InvType::Block,
127 _ => { panic!("bad inventory type field") }
129 },
130 hash: Decodable::consensus_decode(d)?
131 })
132 }
133}
134
135#[cfg(test)]
136mod tests {
137 use super::{GetHeadersMessage, GetBlocksMessage};
138
139 use hex::decode as hex_decode;
140
141 use consensus::encode::{deserialize, serialize};
142 use std::default::Default;
143
144 #[test]
145 fn getblocks_message_test() {
146 let from_sat = hex_decode("72110100014a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b0000000000000000000000000000000000000000000000000000000000000000").unwrap();
147 let genhash = hex_decode("4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b").unwrap();
148
149 let decode: Result<GetBlocksMessage, _> = deserialize(&from_sat);
150 assert!(decode.is_ok());
151 let real_decode = decode.unwrap();
152 assert_eq!(real_decode.version, 70002);
153 assert_eq!(real_decode.locator_hashes.len(), 1);
154 assert_eq!(serialize(&real_decode.locator_hashes[0]), genhash);
155 assert_eq!(real_decode.stop_hash, Default::default());
156
157 assert_eq!(serialize(&real_decode), from_sat);
158 }
159
160 #[test]
161 fn getheaders_message_test() {
162 let from_sat = hex_decode("72110100014a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b0000000000000000000000000000000000000000000000000000000000000000").unwrap();
163 let genhash = hex_decode("4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b").unwrap();
164
165 let decode: Result<GetHeadersMessage, _> = deserialize(&from_sat);
166 assert!(decode.is_ok());
167 let real_decode = decode.unwrap();
168 assert_eq!(real_decode.version, 70002);
169 assert_eq!(real_decode.locator_hashes.len(), 1);
170 assert_eq!(serialize(&real_decode.locator_hashes[0]), genhash);
171 assert_eq!(real_decode.stop_hash, Default::default());
172
173 assert_eq!(serialize(&real_decode), from_sat);
174 }
175}
176