+
+#[cfg(test)]
+mod tests {
+ use crate::ln::msgs::DecodeError;
+ use super::{ChaChaPolyReadAdapter, ChaChaPolyWriteAdapter};
+ use crate::util::ser::{self, FixedLengthReader, LengthReadableArgs, Writeable};
+
+ // Used for for testing various lengths of serialization.
+ #[derive(Debug, PartialEq, Eq)]
+ struct TestWriteable {
+ field1: Vec<u8>,
+ field2: Vec<u8>,
+ field3: Vec<u8>,
+ }
+ impl_writeable_tlv_based!(TestWriteable, {
+ (1, field1, vec_type),
+ (2, field2, vec_type),
+ (3, field3, vec_type),
+ });
+
+ #[test]
+ fn test_chacha_stream_adapters() {
+ // Check that ChaChaPolyReadAdapter and ChaChaPolyWriteAdapter correctly encode and decode an
+ // encrypted object.
+ macro_rules! check_object_read_write {
+ ($obj: expr) => {
+ // First, serialize the object, encrypted with ChaCha20Poly1305.
+ let rho = [42; 32];
+ let writeable_len = $obj.serialized_length() as u64 + 16;
+ let write_adapter = ChaChaPolyWriteAdapter::new(rho, &$obj);
+ let encrypted_writeable_bytes = write_adapter.encode();
+ let encrypted_writeable = &encrypted_writeable_bytes[..];
+
+ // Now deserialize the object back and make sure it matches the original.
+ let mut rd = FixedLengthReader::new(encrypted_writeable, writeable_len);
+ let read_adapter = <ChaChaPolyReadAdapter<TestWriteable>>::read(&mut rd, rho).unwrap();
+ assert_eq!($obj, read_adapter.readable);
+ };
+ }
+
+ // Try a big object that will require multiple write buffers.
+ let big_writeable = TestWriteable {
+ field1: vec![43],
+ field2: vec![44; 4192],
+ field3: vec![45; 4192 + 1],
+ };
+ check_object_read_write!(big_writeable);
+
+ // Try a small object that fits into one write buffer.
+ let small_writeable = TestWriteable {
+ field1: vec![43],
+ field2: vec![44],
+ field3: vec![45],
+ };
+ check_object_read_write!(small_writeable);
+ }
+
+ fn do_chacha_stream_adapters_ser_macros() -> Result<(), DecodeError> {
+ let writeable = TestWriteable {
+ field1: vec![43],
+ field2: vec![44; 4192],
+ field3: vec![45; 4192 + 1],
+ };
+
+ // First, serialize the object into a TLV stream, encrypted with ChaCha20Poly1305.
+ let rho = [42; 32];
+ let write_adapter = ChaChaPolyWriteAdapter::new(rho, &writeable);
+ let mut writer = ser::VecWriter(Vec::new());
+ encode_tlv_stream!(&mut writer, {
+ (1, write_adapter, required),
+ });
+
+ // Now deserialize the object back and make sure it matches the original.
+ let mut read_adapter: Option<ChaChaPolyReadAdapter<TestWriteable>> = None;
+ decode_tlv_stream!(&writer.0[..], {
+ (1, read_adapter, (option: LengthReadableArgs, rho)),
+ });
+ assert_eq!(writeable, read_adapter.unwrap().readable);
+
+ Ok(())
+ }
+
+ #[test]
+ fn chacha_stream_adapters_ser_macros() {
+ // Test that our stream adapters work as expected with the TLV macros.
+ // This also serves to test the `option: $trait` variant of the `_decode_tlv` ser macro.
+ do_chacha_stream_adapters_ser_macros().unwrap()
+ }
+}