Skip to content

Commit 2ec1991

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 801d6e5 commit 2ec1991

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
@@ -18,7 +18,7 @@ use chain::keysinterface::SpendableOutputDescriptor;
1818
use ln::msgs;
1919
use ln::{PaymentPreimage, PaymentHash, PaymentSecret};
2020
use routing::network_graph::NetworkUpdate;
21-
use util::ser::{Writeable, Writer, MaybeReadable, Readable, VecReadWrapper, VecWriteWrapper};
21+
use util::ser::{BigSize, FixedLengthReader, Writeable, Writer, MaybeReadable, Readable, VecReadWrapper, VecWriteWrapper};
2222

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

@@ -265,13 +265,18 @@ impl Writeable for Event {
265265
(2, claim_from_onchain_tx, required),
266266
});
267267
},
268+
// Note that, going forward, all new events must only write data inside of
269+
// `write_tlv_fields`. Versions 0.0.101+ will ignore odd-numbered events that write
270+
// data via `write_tlv_fields`.
268271
}
269272
Ok(())
270273
}
271274
}
272275
impl MaybeReadable for Event {
273276
fn read<R: io::Read>(reader: &mut R) -> Result<Option<Self>, msgs::DecodeError> {
274277
match Readable::read(reader)? {
278+
// Note that we do not write a length-prefixed TLV for FundingGenerationReady events,
279+
// unlike all other events, thus we return immediately here.
275280
0u8 => Ok(None),
276281
1u8 => {
277282
let f = || {
@@ -379,7 +384,19 @@ impl MaybeReadable for Event {
379384
f()
380385
},
381386
// Versions prior to 0.0.100 did not ignore odd types, instead returning InvalidValue.
382-
x if x % 2 == 1 => Ok(None),
387+
// Version 0.0.100 failed to properly ignore odd types, possibly resulting in corrupt
388+
// reads.
389+
x if x % 2 == 1 => {
390+
// If the event is of unknown type, assume it was written with `write_tlv_fields`,
391+
// which prefixes the whole thing with a length BigSize. Because the event is
392+
// odd-type unknown, we should treat it as `Ok(None)` even if it has some TLV
393+
// fields which are event. Thus, we avoid using `read_tlv_fields` and simply read
394+
// exactly the number of bytes specified, ignoring them entirely.
395+
let tlv_len: BigSize = Readable::read(reader)?;
396+
FixedLengthReader::new(reader, tlv_len.0)
397+
.eat_remaining().map_err(|_| msgs::DecodeError::ShortRead)?;
398+
Ok(None)
399+
},
383400
_ => Err(msgs::DecodeError::InvalidValue)
384401
}
385402
}

0 commit comments

Comments
 (0)