Skip to content

Commit 5d0ee86

Browse files
Fix upgradable_required fields to actually be required in lower level macros
When using lower level macros such as read_tlv_stream, upgradable_required fields have been treated as regular options. This is incorrect, they should either be upgradable_options or treated as required fields.
1 parent 70c7161 commit 5d0ee86

File tree

6 files changed

+81
-42
lines changed

6 files changed

+81
-42
lines changed

lightning/src/chain/channelmonitor.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ use crate::chain::onchaintx::OnchainTxHandler;
4949
use crate::chain::package::{CounterpartyOfferedHTLCOutput, CounterpartyReceivedHTLCOutput, HolderFundingOutput, HolderHTLCOutput, PackageSolvingData, PackageTemplate, RevokedOutput, RevokedHTLCOutput};
5050
use crate::chain::Filter;
5151
use crate::util::logger::Logger;
52-
use crate::util::ser::{Readable, ReadableArgs, RequiredWrapper, MaybeReadable, Writer, Writeable, U48};
52+
use crate::util::ser::{Readable, ReadableArgs, RequiredWrapper, MaybeReadable, UpgradableRequired, Writer, Writeable, U48};
5353
use crate::util::byte_utils;
5454
use crate::util::events::Event;
5555
#[cfg(anchors)]
@@ -454,19 +454,15 @@ impl MaybeReadable for OnchainEventEntry {
454454
let mut transaction = None;
455455
let mut block_hash = None;
456456
let mut height = 0;
457-
let mut event = None;
457+
let mut event = UpgradableRequired(None);
458458
read_tlv_fields!(reader, {
459459
(0, txid, required),
460460
(1, transaction, option),
461461
(2, height, required),
462462
(3, block_hash, option),
463463
(4, event, upgradable_required),
464464
});
465-
if let Some(ev) = event {
466-
Ok(Some(Self { txid, transaction, height, block_hash, event: ev }))
467-
} else {
468-
Ok(None)
469-
}
465+
Ok(Some(Self { txid, transaction, height, block_hash, event: _init_tlv_based_struct_field!(event, upgradable_required) }))
470466
}
471467
}
472468

lightning/src/chain/onchaintx.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ use crate::chain::keysinterface::WriteableEcdsaChannelSigner;
3636
use crate::chain::package::PackageSolvingData;
3737
use crate::chain::package::PackageTemplate;
3838
use crate::util::logger::Logger;
39-
use crate::util::ser::{Readable, ReadableArgs, MaybeReadable, Writer, Writeable, VecWriter};
39+
use crate::util::ser::{Readable, ReadableArgs, MaybeReadable, UpgradableRequired, Writer, Writeable, VecWriter};
4040

4141
use crate::io;
4242
use crate::prelude::*;
@@ -106,18 +106,14 @@ impl MaybeReadable for OnchainEventEntry {
106106
let mut txid = Txid::all_zeros();
107107
let mut height = 0;
108108
let mut block_hash = None;
109-
let mut event = None;
109+
let mut event = UpgradableRequired(None);
110110
read_tlv_fields!(reader, {
111111
(0, txid, required),
112112
(1, block_hash, option),
113113
(2, height, required),
114114
(4, event, upgradable_required),
115115
});
116-
if let Some(ev) = event {
117-
Ok(Some(Self { txid, height, block_hash, event: ev }))
118-
} else {
119-
Ok(None)
120-
}
116+
Ok(Some(Self { txid, height, block_hash, event: _init_tlv_based_struct_field!(event, upgradable_required) }))
121117
}
122118
}
123119

lightning/src/routing/gossip.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -883,9 +883,9 @@ impl Readable for ChannelInfo {
883883
(0, features, required),
884884
(1, announcement_received_time, (default_value, 0)),
885885
(2, node_one, required),
886-
(4, one_to_two_wrap, upgradable_required),
886+
(4, one_to_two_wrap, upgradable_option),
887887
(6, node_two, required),
888-
(8, two_to_one_wrap, upgradable_required),
888+
(8, two_to_one_wrap, upgradable_option),
889889
(10, capacity_sats, required),
890890
(12, announcement_message, required),
891891
});
@@ -1161,7 +1161,7 @@ impl Readable for NodeInfo {
11611161

11621162
read_tlv_fields!(reader, {
11631163
(0, _lowest_inbound_channel_fees, option),
1164-
(2, announcement_info_wrap, upgradable_required),
1164+
(2, announcement_info_wrap, upgradable_option),
11651165
(4, channels, vec_type),
11661166
});
11671167

lightning/src/util/events.rs

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use crate::ln::features::ChannelTypeFeatures;
2323
use crate::ln::msgs;
2424
use crate::ln::{PaymentPreimage, PaymentHash, PaymentSecret};
2525
use crate::routing::gossip::NetworkUpdate;
26-
use crate::util::ser::{BigSize, FixedLengthReader, Writeable, Writer, MaybeReadable, Readable, RequiredWrapper, WithoutLength};
26+
use crate::util::ser::{BigSize, FixedLengthReader, Writeable, Writer, MaybeReadable, Readable, RequiredWrapper, UpgradableRequired, WithoutLength};
2727
use crate::routing::router::{RouteHop, RouteParameters};
2828

2929
use bitcoin::{PackedLockTime, Transaction};
@@ -1199,7 +1199,7 @@ impl MaybeReadable for Event {
11991199
let mut payment_id = None;
12001200
read_tlv_fields!(reader, {
12011201
(0, payment_hash, required),
1202-
(1, network_update, upgradable_required),
1202+
(1, network_update, upgradable_option),
12031203
(2, payment_failed_permanently, required),
12041204
(5, path, vec_type),
12051205
(7, short_channel_id, option),
@@ -1276,7 +1276,7 @@ impl MaybeReadable for Event {
12761276
9u8 => {
12771277
let f = || {
12781278
let mut channel_id = [0; 32];
1279-
let mut reason = None;
1279+
let mut reason = UpgradableRequired(None);
12801280
let mut user_channel_id_low_opt: Option<u64> = None;
12811281
let mut user_channel_id_high_opt: Option<u64> = None;
12821282
read_tlv_fields!(reader, {
@@ -1285,15 +1285,14 @@ impl MaybeReadable for Event {
12851285
(2, reason, upgradable_required),
12861286
(3, user_channel_id_high_opt, option),
12871287
});
1288-
if reason.is_none() { return Ok(None); }
12891288

12901289
// `user_channel_id` used to be a single u64 value. In order to remain
12911290
// backwards compatible with versions prior to 0.0.113, the u128 is serialized
12921291
// as two separate u64 values.
12931292
let user_channel_id = (user_channel_id_low_opt.unwrap_or(0) as u128) +
12941293
((user_channel_id_high_opt.unwrap_or(0) as u128) << 64);
12951294

1296-
Ok(Some(Event::ChannelClosed { channel_id, user_channel_id, reason: reason.unwrap() }))
1295+
Ok(Some(Event::ChannelClosed { channel_id, user_channel_id, reason: _init_tlv_based_struct_field!(reason, upgradable_required) }))
12971296
};
12981297
f()
12991298
},
@@ -1349,7 +1348,7 @@ impl MaybeReadable for Event {
13491348
19u8 => {
13501349
let f = || {
13511350
let mut payment_hash = PaymentHash([0; 32]);
1352-
let mut purpose = None;
1351+
let mut purpose = UpgradableRequired(None);
13531352
let mut amount_msat = 0;
13541353
let mut receiver_node_id = None;
13551354
read_tlv_fields!(reader, {
@@ -1358,11 +1357,10 @@ impl MaybeReadable for Event {
13581357
(2, purpose, upgradable_required),
13591358
(4, amount_msat, required),
13601359
});
1361-
if purpose.is_none() { return Ok(None); }
13621360
Ok(Some(Event::PaymentClaimed {
13631361
receiver_node_id,
13641362
payment_hash,
1365-
purpose: purpose.unwrap(),
1363+
purpose: _init_tlv_based_struct_field!(purpose, upgradable_required),
13661364
amount_msat,
13671365
}))
13681366
};
@@ -1410,22 +1408,15 @@ impl MaybeReadable for Event {
14101408
25u8 => {
14111409
let f = || {
14121410
let mut prev_channel_id = [0; 32];
1413-
let mut failed_next_destination_opt = None;
1411+
let mut failed_next_destination_opt = UpgradableRequired(None);
14141412
read_tlv_fields!(reader, {
14151413
(0, prev_channel_id, required),
14161414
(2, failed_next_destination_opt, upgradable_required),
14171415
});
1418-
if let Some(failed_next_destination) = failed_next_destination_opt {
1419-
Ok(Some(Event::HTLCHandlingFailed {
1420-
prev_channel_id,
1421-
failed_next_destination,
1422-
}))
1423-
} else {
1424-
// If we fail to read a `failed_next_destination` assume it's because
1425-
// `MaybeReadable::read` returned `Ok(None)`, though it's also possible we
1426-
// were simply missing the field.
1427-
Ok(None)
1428-
}
1416+
Ok(Some(Event::HTLCHandlingFailed {
1417+
prev_channel_id,
1418+
failed_next_destination: _init_tlv_based_struct_field!(failed_next_destination_opt, upgradable_required),
1419+
}))
14291420
};
14301421
f()
14311422
},

lightning/src/util/ser.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,18 @@ impl<T: Readable> From<T> for RequiredWrapper<T> {
303303
fn from(t: T) -> RequiredWrapper<T> { RequiredWrapper(Some(t)) }
304304
}
305305

306+
/// Wrapper to read a required (non-optional) TLV record that may have been upgraded without
307+
/// backwards compat.
308+
pub struct UpgradableRequired<T: MaybeReadable>(pub Option<T>);
309+
impl<T: MaybeReadable> MaybeReadable for UpgradableRequired<T> {
310+
#[inline]
311+
fn read<R: Read>(reader: &mut R) -> Result<Option<Self>, DecodeError> {
312+
let tlv = MaybeReadable::read(reader)?;
313+
if let Some(tlv) = tlv { return Ok(Some(Self(Some(tlv)))) }
314+
Ok(None)
315+
}
316+
}
317+
306318
pub(crate) struct U48(pub u64);
307319
impl Writeable for U48 {
308320
#[inline]

lightning/src/util/ser_macros.rs

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ macro_rules! _check_decoded_tlv_order {
217217
// no-op
218218
}};
219219
($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, upgradable_required) => {{
220-
// no-op
220+
_check_decoded_tlv_order!($last_seen_type, $typ, $type, $field, required)
221221
}};
222222
($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, upgradable_option) => {{
223223
// no-op
@@ -259,7 +259,7 @@ macro_rules! _check_missing_tlv {
259259
// no-op
260260
}};
261261
($last_seen_type: expr, $type: expr, $field: ident, upgradable_required) => {{
262-
// no-op
262+
_check_missing_tlv!($last_seen_type, $type, $field, required)
263263
}};
264264
($last_seen_type: expr, $type: expr, $field: ident, upgradable_option) => {{
265265
// no-op
@@ -293,7 +293,10 @@ macro_rules! _decode_tlv {
293293
$field = Some($crate::util::ser::Readable::read(&mut $reader)?);
294294
}};
295295
($reader: expr, $field: ident, upgradable_required) => {{
296-
$field = $crate::util::ser::MaybeReadable::read(&mut $reader)?;
296+
$field = match $crate::util::ser::MaybeReadable::read(&mut $reader)? {
297+
Some(res) => res,
298+
_ => return Ok(None)
299+
};
297300
}};
298301
($reader: expr, $field: ident, upgradable_option) => {{
299302
$field = $crate::util::ser::MaybeReadable::read(&mut $reader)?;
@@ -636,7 +639,7 @@ macro_rules! _init_tlv_based_struct_field {
636639
$field
637640
};
638641
($field: ident, upgradable_required) => {
639-
if $field.is_none() { return Ok(None); } else { $field.unwrap() }
642+
$field.0.unwrap()
640643
};
641644
($field: ident, upgradable_option) => {
642645
$field
@@ -671,7 +674,7 @@ macro_rules! _init_tlv_field_var {
671674
let mut $field = None;
672675
};
673676
($field: ident, upgradable_required) => {
674-
let mut $field = None;
677+
let mut $field = $crate::util::ser::UpgradableRequired(None);
675678
};
676679
($field: ident, upgradable_option) => {
677680
let mut $field = None;
@@ -1050,6 +1053,47 @@ mod tests {
10501053
(0xdeadbeef1badbeef, 0x1bad1dea, Some(0x01020304)));
10511054
}
10521055

1056+
#[derive(Debug, PartialEq)]
1057+
struct TestUpgradable {
1058+
a: u32,
1059+
b: u32,
1060+
c: Option<u32>,
1061+
}
1062+
1063+
fn upgradable_tlv_reader(s: &[u8]) -> Result<Option<TestUpgradable>, DecodeError> {
1064+
let mut s = Cursor::new(s);
1065+
let mut a = 0;
1066+
let mut b = 0;
1067+
let mut c: Option<u32> = None;
1068+
decode_tlv_stream!(&mut s, {(2, a, upgradable_required), (3, b, upgradable_required), (4, c, upgradable_option)});
1069+
Ok(Some(TestUpgradable { a, b, c, }))
1070+
}
1071+
1072+
#[test]
1073+
fn upgradable_tlv_simple_good_cases() {
1074+
assert_eq!(upgradable_tlv_reader(&::hex::decode(
1075+
concat!("0204deadbeef", "03041bad1dea", "0404deadbeef")
1076+
).unwrap()[..]).unwrap(),
1077+
Some(TestUpgradable { a: 0xdeadbeef, b: 0x1bad1dea, c: Some(0xdeadbeef) }));
1078+
1079+
assert_eq!(upgradable_tlv_reader(&::hex::decode(
1080+
concat!("0204deadbeef", "03041bad1dea")
1081+
).unwrap()[..]).unwrap(),
1082+
Some(TestUpgradable { a: 0xdeadbeef, b: 0x1bad1dea, c: None}));
1083+
}
1084+
1085+
#[test]
1086+
fn missing_required_upgradable() {
1087+
if let Err(DecodeError::InvalidValue) = upgradable_tlv_reader(&::hex::decode(
1088+
concat!("0100", "0204deadbeef")
1089+
).unwrap()[..]) {
1090+
} else { panic!(); }
1091+
if let Err(DecodeError::InvalidValue) = upgradable_tlv_reader(&::hex::decode(
1092+
concat!("0100", "03041bad1dea")
1093+
).unwrap()[..]) {
1094+
} else { panic!(); }
1095+
}
1096+
10531097
// BOLT TLV test cases
10541098
fn tlv_reader_n1(s: &[u8]) -> Result<(Option<HighZeroBytesDroppedBigSize<u64>>, Option<u64>, Option<(PublicKey, u64, u64)>, Option<u16>), DecodeError> {
10551099
let mut s = Cursor::new(s);

0 commit comments

Comments
 (0)