Skip to content

Commit 5262e77

Browse files
authored
Merge pull request #1087 from TheBlueMatt/2021-09-event-backwards-compat-fix
Fix future unknown `Event` variant backwards compatibility
2 parents 4d42284 + 71e0173 commit 5262e77

File tree

1 file changed

+19
-2
lines changed

1 file changed

+19
-2
lines changed

lightning/src/util/events.rs

+19-2
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)