From: Matt Corallo Date: Wed, 22 Sep 2021 19:00:30 +0000 (+0000) Subject: Use Infallible for the unconstructable default custom message type X-Git-Tag: v0.0.101~2^2~2 X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=commitdiff_plain;h=e82318d374fc6dd8e0aec5155bb06bca432ae4b7;p=rust-lightning Use Infallible for the unconstructable default custom message type 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. --- diff --git a/lightning/src/ln/peer_handler.rs b/lightning/src/ln/peer_handler.rs index 80edebc69..22568e506 100644 --- a/lightning/src/ln/peer_handler.rs +++ b/lightning/src/ln/peer_handler.rs @@ -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(&self, _: &mut W) -> Result<(), io::Error> { unreachable!(); } } impl wire::CustomMessageReader for IgnoringMessageHandler { - type CustomMessage = (); + type CustomMessage = Infallible; fn read(&self, _message_type: u16, _buffer: &mut R) -> Result, msgs::DecodeError> { Ok(None) } diff --git a/lightning/src/ln/wire.rs b/lightning/src/ln/wire.rs index ee1e79639..d3cc257f5 100644 --- a/lightning/src/ln/wire.rs +++ b/lightning/src/ln/wire.rs @@ -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); diff --git a/lightning/src/util/ser.rs b/lightning/src/util/ser.rs index c06293269..47bdf04f8 100644 --- a/lightning/src/util/ser.rs +++ b/lightning/src/util/ser.rs @@ -879,6 +879,11 @@ impl Writeable for (A, B, C) { } } +impl Writeable for () { + fn write(&self, _: &mut W) -> Result<(), io::Error> { + Ok(()) + } +} impl Readable for () { fn read(_r: &mut R) -> Result { Ok(()) @@ -892,7 +897,6 @@ impl Writeable for String { w.write_all(self.as_bytes()) } } - impl Readable for String { #[inline] fn read(r: &mut R) -> Result {