mwc_bch/messages/
block_locator.rs1use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
2use messages::message::Payload;
3use messages::version::MIN_SUPPORTED_PROTOCOL_VERSION;
4use std::io;
5use std::io::{Read, Write};
6use util::{var_int, Error, Hash256, Result, Serializable};
7
8pub const NO_HASH_STOP: Hash256 = Hash256([0; 32]);
10
11#[derive(Debug, Default, PartialEq, Eq, Hash, Clone)]
13pub struct BlockLocator {
14 pub version: u32,
16 pub block_locator_hashes: Vec<Hash256>,
18 pub hash_stop: Hash256,
20}
21
22impl BlockLocator {
23 pub fn validate(&self) -> Result<()> {
25 if self.version < MIN_SUPPORTED_PROTOCOL_VERSION as u32 {
26 let msg = format!("Unsupported protocol version: {}", self.version);
27 return Err(Error::BadData(msg));
28 }
29 Ok(())
30 }
31}
32
33impl Serializable<BlockLocator> for BlockLocator {
34 fn read(reader: &mut dyn Read) -> Result<BlockLocator> {
35 let version = reader.read_u32::<LittleEndian>()?;
36 let num_hashes = var_int::read(reader)?;
37 let mut block_locator_hashes = Vec::new();
38 for _i in 0..num_hashes {
39 block_locator_hashes.push(Hash256::read(reader)?);
40 }
41 let hash_stop = Hash256::read(reader)?;
42 Ok(BlockLocator {
43 version,
44 block_locator_hashes,
45 hash_stop,
46 })
47 }
48
49 fn write(&self, writer: &mut dyn Write) -> io::Result<()> {
50 writer.write_u32::<LittleEndian>(self.version)?;
51 var_int::write(self.block_locator_hashes.len() as u64, writer)?;
52 for hash in self.block_locator_hashes.iter() {
53 hash.write(writer)?;
54 }
55 self.hash_stop.write(writer)?;
56 Ok(())
57 }
58}
59
60impl Payload<BlockLocator> for BlockLocator {
61 fn size(&self) -> usize {
62 4 + var_int::size(self.block_locator_hashes.len() as u64)
63 + self.block_locator_hashes.len() * 32
64 + 32
65 }
66}
67
68#[cfg(test)]
69mod tests {
70 use super::*;
71 use std::io::Cursor;
72
73 #[test]
74 fn write_read() {
75 let mut v = Vec::new();
76 let p = BlockLocator {
77 version: 12345,
78 block_locator_hashes: vec![
79 NO_HASH_STOP,
80 Hash256::decode("6677889900667788990066778899006677889900667788990066778899006677")
81 .unwrap(),
82 ],
83 hash_stop: Hash256::decode(
84 "1122334455112233445511223344551122334455112233445511223344551122",
85 ).unwrap(),
86 };
87 p.write(&mut v).unwrap();
88 assert!(v.len() == p.size());
89 assert!(BlockLocator::read(&mut Cursor::new(&v)).unwrap() == p);
90 }
91}