cs_mwc_bch/messages/
inv.rs

1use messages::inv_vect::InvVect;
2use messages::message::Payload;
3use std::fmt;
4use std::io;
5use std::io::{Read, Write};
6use util::{var_int, Error, Result, Serializable};
7
8/// Maximum number of objects in an inv message
9pub const MAX_INV_ENTRIES: usize = 50000;
10
11/// Inventory payload describing objects a node knows about
12#[derive(Default, PartialEq, Eq, Hash, Clone)]
13pub struct Inv {
14    /// List of objects announced
15    pub objects: Vec<InvVect>,
16}
17
18impl Serializable<Inv> for Inv {
19    fn read(reader: &mut dyn Read) -> Result<Inv> {
20        let num_objects = var_int::read(reader)? as usize;
21        if num_objects > MAX_INV_ENTRIES {
22            let msg = format!("Num objects exceeded maximum: {}", num_objects);
23            return Err(Error::BadData(msg));
24        }
25        let mut objects = Vec::with_capacity(num_objects);
26        for _ in 0..num_objects {
27            objects.push(InvVect::read(reader)?);
28        }
29        Ok(Inv { objects })
30    }
31
32    fn write(&self, writer: &mut dyn Write) -> io::Result<()> {
33        var_int::write(self.objects.len() as u64, writer)?;
34        for object in self.objects.iter() {
35            object.write(writer)?;
36        }
37        Ok(())
38    }
39}
40
41impl Payload<Inv> for Inv {
42    fn size(&self) -> usize {
43        var_int::size(self.objects.len() as u64) + InvVect::SIZE * self.objects.len()
44    }
45}
46
47impl fmt::Debug for Inv {
48    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
49        if self.objects.len() <= 3 {
50            f.debug_struct("Inv")
51                .field("objects", &self.objects)
52                .finish()
53        } else {
54            let s = format!("[<{} inventory vectors>]", self.objects.len());
55            f.debug_struct("Inv").field("objects", &s).finish()
56        }
57    }
58}
59
60#[cfg(test)]
61mod tests {
62    use super::*;
63    use messages::inv_vect::{INV_VECT_BLOCK, INV_VECT_TX};
64    use std::io::Cursor;
65    use util::Hash256;
66
67    #[test]
68    fn write_read() {
69        let iv1 = InvVect {
70            obj_type: INV_VECT_TX,
71            hash: Hash256([8; 32]),
72        };
73        let iv2 = InvVect {
74            obj_type: INV_VECT_BLOCK,
75            hash: Hash256([9; 32]),
76        };
77        let mut inv = Inv {
78            objects: Vec::new(),
79        };
80        inv.objects.push(iv1);
81        inv.objects.push(iv2);
82        let mut v = Vec::new();
83        inv.write(&mut v).unwrap();
84        assert!(v.len() == inv.size());
85        assert!(Inv::read(&mut Cursor::new(&v)).unwrap() == inv);
86    }
87
88    #[test]
89    fn too_many_objects() {
90        let mut inv = Inv {
91            objects: Vec::new(),
92        };
93        for _i in 0..MAX_INV_ENTRIES + 1 {
94            let inv_vect = InvVect {
95                obj_type: INV_VECT_TX,
96                hash: Hash256([8; 32]),
97            };
98            inv.objects.push(inv_vect);
99        }
100        let mut v = Vec::new();
101        inv.write(&mut v).unwrap();
102        assert!(Inv::read(&mut Cursor::new(&v)).is_err());
103    }
104}