Use Infallible for the unconstructable default custom message type
authorMatt Corallo <git@bluematt.me>
Wed, 22 Sep 2021 19:00:30 +0000 (19:00 +0000)
committerMatt Corallo <git@bluematt.me>
Wed, 22 Sep 2021 22:01:40 +0000 (22:01 +0000)
When we landed custom messages, we used the empty tuple for the
custom message type for `IgnoringMessageHandler`. This was fine,
except that we also implemented `Writeable` to panic when writing
a `()`. Later, we added support for anchor output construction in
CommitmentTransaction, signified by setting a field to `Some(())`,
which is serialized as-is.

This causes us to panic when writing a `CommitmentTransaction`
with `opt_anchors` set. Note that we never set it inside of LDK,
but downstream users may.

Instead, we implement `Writeable` to write nothing for `()` and use
`core::convert::Infallible` for the default custom message type as
it is, appropriately, unconstructable.

This also makes it easier to implement various things in bindings,
as we can always assume `Infallible`-conversion logic is
unreachable.

lightning/src/ln/peer_handler.rs
lightning/src/ln/wire.rs
lightning/src/util/ser.rs

index 80edebc69b428bc5c16db95899005c5dac1f9e05..22568e506668f127a3f8d179f8df356d383724cd 100644 (file)
@@ -37,6 +37,7 @@ use sync::{Arc, Mutex};
 use core::sync::atomic::{AtomicUsize, Ordering};
 use core::{cmp, hash, fmt, mem};
 use core::ops::Deref;
+use core::convert::Infallible;
 #[cfg(feature = "std")] use std::error;
 
 use bitcoin::hashes::sha256::Hash as Sha256;
@@ -80,21 +81,21 @@ impl Deref for IgnoringMessageHandler {
        fn deref(&self) -> &Self { self }
 }
 
-impl wire::Type for () {
+// Implement Type for Infallible, note that it cannot be constructed, and thus you can never call a
+// method that takes self for it.
+impl wire::Type for Infallible {
        fn type_id(&self) -> u16 {
-               // We should never call this for `DummyCustomType`
                unreachable!();
        }
 }
-
-impl Writeable for () {
+impl Writeable for Infallible {
        fn write<W: Writer>(&self, _: &mut W) -> Result<(), io::Error> {
                unreachable!();
        }
 }
 
 impl wire::CustomMessageReader for IgnoringMessageHandler {
-       type CustomMessage = ();
+       type CustomMessage = Infallible;
        fn read<R: io::Read>(&self, _message_type: u16, _buffer: &mut R) -> Result<Option<Self::CustomMessage>, msgs::DecodeError> {
                Ok(None)
        }
index ee1e7963949fbebd87dc08bc76af21e6680d296c..d3cc257f5a6b18cb1776475b4fec69949521e1d6 100644 (file)
@@ -457,6 +457,10 @@ mod tests {
                }
        }
 
+       impl Type for () {
+               fn type_id(&self) -> u16 { unreachable!(); }
+       }
+
        #[test]
        fn is_even_message_type() {
                let message = Message::<()>::Unknown(42);
index c06293269ec0ffc28727a3d2624e92a9f95d1319..47bdf04f8750ac8d2562f032c7232d997f36c3b4 100644 (file)
@@ -879,6 +879,11 @@ impl<A: Writeable, B: Writeable, C: Writeable> Writeable for (A, B, C) {
        }
 }
 
+impl Writeable for () {
+       fn write<W: Writer>(&self, _: &mut W) -> Result<(), io::Error> {
+               Ok(())
+       }
+}
 impl Readable for () {
        fn read<R: Read>(_r: &mut R) -> Result<Self, DecodeError> {
                Ok(())
@@ -892,7 +897,6 @@ impl Writeable for String {
                w.write_all(self.as_bytes())
        }
 }
-
 impl Readable for String {
        #[inline]
        fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {