6125e5afd611d3dde51a8713b7b3c4f4cd097edf
[rust-lightning] / fuzz / src / msg_targets / utils.rs
1 #![macro_use]
2
3 use lightning::util::ser::Writer;
4 pub struct VecWriter(pub Vec<u8>);
5 impl Writer for VecWriter {
6         fn write_all(&mut self, buf: &[u8]) -> Result<(), ::std::io::Error> {
7                 assert!(self.0.capacity() >= self.0.len() + buf.len());
8                 self.0.extend_from_slice(buf);
9                 Ok(())
10         }
11         fn size_hint(&mut self, size: usize) {
12                 self.0.reserve_exact(size);
13         }
14 }
15
16 // We attempt to test the strictest behavior we can for a given message, however, some messages
17 // have different expected behavior. You can see which messages have which behavior in
18 // gen_target.sh, but, in general, the *_announcement messages have to round-trip exactly (as
19 // otherwise we'd invalidate the signatures), most messages just need to round-trip up to the
20 // amount of data we know how to interpret, and some messages we may throw out invalid stuff (eg
21 // if an error message isn't valid UTF-8 we cant String-ize it), so they wont roundtrip correctly.
22
23 // Tests a message that must survive roundtrip exactly, though may not empty the read buffer
24 // entirely
25 #[macro_export]
26 macro_rules! test_msg {
27         ($MsgType: path, $data: ident) => {
28                 {
29                         use lightning::util::ser::{Writeable, Readable};
30                         let mut r = ::std::io::Cursor::new($data);
31                         if let Ok(msg) = <$MsgType as Readable>::read(&mut r) {
32                                 let p = r.position() as usize;
33                                 let mut w = VecWriter(Vec::new());
34                                 msg.write(&mut w).unwrap();
35
36                                 assert_eq!(w.0.len(), p);
37                                 assert_eq!(&r.into_inner()[..p], &w.0[..p]);
38                         }
39                 }
40         }
41 }
42
43 // Tests a message that may lose data on roundtrip, but shoulnd't lose data compared to our
44 // re-serialization.
45 #[macro_export]
46 macro_rules! test_msg_simple {
47         ($MsgType: path, $data: ident) => {
48                 {
49                         use lightning::util::ser::{Writeable, Readable};
50                         let mut r = ::std::io::Cursor::new($data);
51                         if let Ok(msg) = <$MsgType as Readable>::read(&mut r) {
52                                 let mut w = VecWriter(Vec::new());
53                                 msg.write(&mut w).unwrap();
54
55                                 let msg = <$MsgType as Readable>::read(&mut ::std::io::Cursor::new(&w.0)).unwrap();
56                                 let mut w_two = VecWriter(Vec::new());
57                                 msg.write(&mut w_two).unwrap();
58                                 assert_eq!(&w.0[..], &w_two.0[..]);
59                         }
60                 }
61         }
62 }
63
64 // Tests a message that must survive roundtrip exactly, and must exactly empty the read buffer and
65 // split it back out on re-serialization.
66 #[macro_export]
67 macro_rules! test_msg_exact {
68         ($MsgType: path, $data: ident) => {
69                 {
70                         use lightning::util::ser::{Writeable, Readable};
71                         let mut r = ::std::io::Cursor::new($data);
72                         if let Ok(msg) = <$MsgType as Readable>::read(&mut r) {
73                                 let mut w = VecWriter(Vec::new());
74                                 msg.write(&mut w).unwrap();
75                                 assert_eq!(&r.into_inner()[..], &w.0[..]);
76                         }
77                 }
78         }
79 }
80
81 // Tests a message that must survive roundtrip exactly, modulo one "hole" which may be set to 0s on
82 // re-serialization.
83 #[macro_export]
84 macro_rules! test_msg_hole {
85         ($MsgType: path, $data: ident, $hole: expr, $hole_len: expr) => {
86                 {
87                         use lightning::util::ser::{Writeable, Readable};
88                         let mut r = ::std::io::Cursor::new($data);
89                         if let Ok(msg) = <$MsgType as Readable>::read(&mut r) {
90                                 let mut w = VecWriter(Vec::new());
91                                 msg.write(&mut w).unwrap();
92                                 let p = w.0.len() as usize;
93
94                                 assert_eq!(w.0.len(), p);
95                                 assert_eq!(&r.get_ref()[..$hole], &w.0[..$hole]);
96                                 assert_eq!(&r.get_ref()[$hole+$hole_len..p], &w.0[$hole+$hole_len..]);
97                         }
98                 }
99         }
100 }