Skip to content

Commit 8868a88

Browse files
committed
Add forward-compat due serialization variants of HTLCFailureMsg
Going forward, all lightning messages have a TLV stream suffix, allowing new fields to be added as needed. In the P2P protocol, messages have an explicit length, so there is no implied length in the TLV stream itself. HTLCFailureMsg enum variants have messages in them, but without a size prefix or any explicit end. Thus, if a HTLCFailureMsg is read as a part of a ChannelManager, with a TLV stream at the end, there is no way to differentiate between the end of the message and the next field(s) in the ChannelManager. Here we add two new variant values for HTLCFailureMsg variants in the read path, allowing us to switch to the new values if/when we add new TLV fields in UpdateFailHTLC or UpdateFailMalformedHTLC so that older versions can still read the new TLV fields.
1 parent 4c4d99b commit 8868a88

File tree

1 file changed

+69
-5
lines changed

1 file changed

+69
-5
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 69 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ use chain::keysinterface::{Sign, KeysInterface, KeysManager, InMemorySigner};
5555
use util::config::UserConfig;
5656
use util::events::{EventHandler, EventsProvider, MessageSendEvent, MessageSendEventsProvider};
5757
use util::{byte_utils, events};
58-
use util::ser::{Readable, ReadableArgs, MaybeReadable, Writeable, Writer};
58+
use util::ser::{BigSize, FixedLengthReader, Readable, ReadableArgs, MaybeReadable, Writeable, Writer};
5959
use util::chacha20::{ChaCha20, ChaChaReader};
6060
use util::logger::{Logger, Level};
6161
use util::errors::APIError;
@@ -4841,10 +4841,74 @@ impl_writeable_tlv_based!(PendingHTLCInfo, {
48414841
(8, outgoing_cltv_value, required)
48424842
});
48434843

4844-
impl_writeable_tlv_based_enum!(HTLCFailureMsg, ;
4845-
(0, Relay),
4846-
(1, Malformed),
4847-
);
4844+
4845+
impl Writeable for HTLCFailureMsg {
4846+
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
4847+
match self {
4848+
Self::Relay(msgs::UpdateFailHTLC { channel_id, htlc_id, reason }) => {
4849+
0u8.write(writer)?;
4850+
channel_id.write(writer)?;
4851+
htlc_id.write(writer)?;
4852+
reason.write(writer)?;
4853+
},
4854+
Self::Malformed(msgs::UpdateFailMalformedHTLC {
4855+
channel_id, htlc_id, sha256_of_onion, failure_code
4856+
}) => {
4857+
1u8.write(writer)?;
4858+
channel_id.write(writer)?;
4859+
htlc_id.write(writer)?;
4860+
sha256_of_onion.write(writer)?;
4861+
failure_code.write(writer)?;
4862+
},
4863+
}
4864+
Ok(())
4865+
}
4866+
}
4867+
4868+
impl Readable for HTLCFailureMsg {
4869+
fn read<R: Read>(reader: &mut R) -> Result<Self, DecodeError> {
4870+
let id: u8 = Readable::read(reader)?;
4871+
match id {
4872+
0 => {
4873+
Ok(Self::Relay(msgs::UpdateFailHTLC {
4874+
channel_id: Readable::read(reader)?,
4875+
htlc_id: Readable::read(reader)?,
4876+
reason: Readable::read(reader)?,
4877+
}))
4878+
},
4879+
1 => {
4880+
Ok(Self::Malformed(msgs::UpdateFailMalformedHTLC {
4881+
channel_id: Readable::read(reader)?,
4882+
htlc_id: Readable::read(reader)?,
4883+
sha256_of_onion: Readable::read(reader)?,
4884+
failure_code: Readable::read(reader)?,
4885+
}))
4886+
},
4887+
// In versions prior to 0.0.101, HTLCFailureMsg objects were written with type 0 or 1 but
4888+
// weren't length-prefixed and thus didn't support reading the TLV stream suffix of the network
4889+
// messages contained in the variants.
4890+
// In version 0.0.101, support for reading the variants with these types was added, and
4891+
// we should migrate to writing these variants when UpdateFailHTLC or
4892+
// UpdateFailMalformedHTLC get TLV fields.
4893+
2 => {
4894+
let length: BigSize = Readable::read(reader)?;
4895+
let mut s = FixedLengthReader::new(reader, length.0);
4896+
let res = Readable::read(&mut s)?;
4897+
s.eat_remaining()?; // Return ShortRead if there's actually not enough bytes
4898+
Ok(Self::Relay(res))
4899+
},
4900+
3 => {
4901+
let length: BigSize = Readable::read(reader)?;
4902+
let mut s = FixedLengthReader::new(reader, length.0);
4903+
let res = Readable::read(&mut s)?;
4904+
s.eat_remaining()?; // Return ShortRead if there's actually not enough bytes
4905+
Ok(Self::Relay(res))
4906+
},
4907+
_ => Err(DecodeError::UnknownRequiredFeature),
4908+
}
4909+
}
4910+
}
4911+
48484912
impl_writeable_tlv_based_enum!(PendingHTLCStatus, ;
48494913
(0, Forward),
48504914
(1, Fail),

0 commit comments

Comments
 (0)