Skip to content

Commit 71e0173

Browse files
committed
Fix future unknown Event variant backwards compatibility
In 8ffc2d1, in 0.0.100, we added a backwards compatibility feature to the reading of `Event`s - if the type was unknown and odd, we'd simply ignore the event and treat it as no event. However, we failed to read the length-prefixed TLV stream when doing so, resulting in us reading some of the skipped-event data as the next event or other data in the ChannelManager. We fix this by reading the varint length prefix written, then skipping that many bytes when we come across an unknown odd event type.
1 parent 2cf42aa commit 71e0173

File tree

1 file changed

+19
-2
lines changed

1 file changed

+19
-2
lines changed

lightning/src/util/events.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use ln::msgs;
1919
use ln::msgs::DecodeError;
2020
use ln::{PaymentPreimage, PaymentHash, PaymentSecret};
2121
use routing::network_graph::NetworkUpdate;
22-
use util::ser::{Writeable, Writer, MaybeReadable, Readable, VecReadWrapper, VecWriteWrapper};
22+
use util::ser::{BigSize, FixedLengthReader, Writeable, Writer, MaybeReadable, Readable, VecReadWrapper, VecWriteWrapper};
2323

2424
use bitcoin::blockdata::script::Script;
2525

@@ -335,13 +335,18 @@ impl Writeable for Event {
335335
(2, reason, required)
336336
});
337337
},
338+
// Note that, going forward, all new events must only write data inside of
339+
// `write_tlv_fields`. Versions 0.0.101+ will ignore odd-numbered events that write
340+
// data via `write_tlv_fields`.
338341
}
339342
Ok(())
340343
}
341344
}
342345
impl MaybeReadable for Event {
343346
fn read<R: io::Read>(reader: &mut R) -> Result<Option<Self>, msgs::DecodeError> {
344347
match Readable::read(reader)? {
348+
// Note that we do not write a length-prefixed TLV for FundingGenerationReady events,
349+
// unlike all other events, thus we return immediately here.
345350
0u8 => Ok(None),
346351
1u8 => {
347352
let f = || {
@@ -459,7 +464,19 @@ impl MaybeReadable for Event {
459464
Ok(Some(Event::ChannelClosed { channel_id, reason: reason.unwrap() }))
460465
},
461466
// Versions prior to 0.0.100 did not ignore odd types, instead returning InvalidValue.
462-
x if x % 2 == 1 => Ok(None),
467+
// Version 0.0.100 failed to properly ignore odd types, possibly resulting in corrupt
468+
// reads.
469+
x if x % 2 == 1 => {
470+
// If the event is of unknown type, assume it was written with `write_tlv_fields`,
471+
// which prefixes the whole thing with a length BigSize. Because the event is
472+
// odd-type unknown, we should treat it as `Ok(None)` even if it has some TLV
473+
// fields that are even. Thus, we avoid using `read_tlv_fields` and simply read
474+
// exactly the number of bytes specified, ignoring them entirely.
475+
let tlv_len: BigSize = Readable::read(reader)?;
476+
FixedLengthReader::new(reader, tlv_len.0)
477+
.eat_remaining().map_err(|_| msgs::DecodeError::ShortRead)?;
478+
Ok(None)
479+
},
463480
_ => Err(msgs::DecodeError::InvalidValue)
464481
}
465482
}

0 commit comments

Comments
 (0)