Skip to content

Commit 1988cb2

Browse files
authored
Merge pull request #1519 from tnull/2022-06-require-htlc-max
Make `htlc_maximum_msat` a required field.
2 parents f26e854 + 8b86ed7 commit 1988cb2

File tree

13 files changed

+488
-236
lines changed

13 files changed

+488
-236
lines changed

.github/workflows/build.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -232,14 +232,14 @@ jobs:
232232
EXPECTED_ROUTING_GRAPH_SNAPSHOT_SHASUM: 05a5361278f68ee2afd086cc04a1f927a63924be451f3221d380533acfacc303
233233
- name: Fetch rapid graph sync reference input
234234
run: |
235-
curl --verbose -L -o lightning-rapid-gossip-sync/res/full_graph.lngossip https://bitcoin.ninja/ldk-compressed_graph-bc08df7542-2022-05-05.bin
235+
curl --verbose -L -o lightning-rapid-gossip-sync/res/full_graph.lngossip https://bitcoin.ninja/ldk-compressed_graph-285cb27df79-2022-07-21.bin
236236
echo "Sha sum: $(sha256sum lightning-rapid-gossip-sync/res/full_graph.lngossip | awk '{ print $1 }')"
237237
if [ "$(sha256sum lightning-rapid-gossip-sync/res/full_graph.lngossip | awk '{ print $1 }')" != "${EXPECTED_RAPID_GOSSIP_SHASUM}" ]; then
238238
echo "Bad hash"
239239
exit 1
240240
fi
241241
env:
242-
EXPECTED_RAPID_GOSSIP_SHASUM: 9637b91cea9d64320cf48fc0787c70fe69fc062f90d3512e207044110cadfd7b
242+
EXPECTED_RAPID_GOSSIP_SHASUM: e0f5d11641c11896d7af3a2246d3d6c3f1720b7d2d17aab321ecce82e6b7deb8
243243
- name: Test with Network Graph on Rust ${{ matrix.toolchain }}
244244
run: |
245245
cd lightning

lightning-rapid-gossip-sync/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ mod tests {
240240
let sync_result = rapid_sync
241241
.sync_network_graph_with_file_path("./res/full_graph.lngossip");
242242
if let Err(crate::error::GraphSyncError::DecodeError(DecodeError::Io(io_error))) = &sync_result {
243-
let error_string = format!("Input file lightning-rapid-gossip-sync/res/full_graph.lngossip is missing! Download it from https://bitcoin.ninja/ldk-compressed_graph-bc08df7542-2022-05-05.bin\n\n{:?}", io_error);
243+
let error_string = format!("Input file lightning-rapid-gossip-sync/res/full_graph.lngossip is missing! Download it from https://bitcoin.ninja/ldk-compressed_graph-285cb27df79-2022-07-21.bin\n\n{:?}", io_error);
244244
#[cfg(not(require_route_graph_test))]
245245
{
246246
println!("{}", error_string);

lightning-rapid-gossip-sync/src/processing.rs

+6-23
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use bitcoin::BlockHash;
88
use bitcoin::secp256k1::PublicKey;
99

1010
use lightning::ln::msgs::{
11-
DecodeError, ErrorAction, LightningError, OptionalField, UnsignedChannelUpdate,
11+
DecodeError, ErrorAction, LightningError, UnsignedChannelUpdate,
1212
};
1313
use lightning::routing::gossip::NetworkGraph;
1414
use lightning::util::logger::Logger;
@@ -119,12 +119,7 @@ impl<NG: Deref<Target=NetworkGraph<L>>, L: Deref> RapidGossipSync<NG, L> where L
119119
let default_htlc_minimum_msat: u64 = Readable::read(&mut read_cursor)?;
120120
let default_fee_base_msat: u32 = Readable::read(&mut read_cursor)?;
121121
let default_fee_proportional_millionths: u32 = Readable::read(&mut read_cursor)?;
122-
let tentative_default_htlc_maximum_msat: u64 = Readable::read(&mut read_cursor)?;
123-
let default_htlc_maximum_msat = if tentative_default_htlc_maximum_msat == u64::max_value() {
124-
OptionalField::Absent
125-
} else {
126-
OptionalField::Present(tentative_default_htlc_maximum_msat)
127-
};
122+
let default_htlc_maximum_msat: u64 = Readable::read(&mut read_cursor)?;
128123

129124
for _ in 0..update_count {
130125
let scid_delta: BigSize = Readable::read(read_cursor)?;
@@ -147,7 +142,7 @@ impl<NG: Deref<Target=NetworkGraph<L>>, L: Deref> RapidGossipSync<NG, L> where L
147142
flags: standard_channel_flags,
148143
cltv_expiry_delta: default_cltv_expiry_delta,
149144
htlc_minimum_msat: default_htlc_minimum_msat,
150-
htlc_maximum_msat: default_htlc_maximum_msat.clone(),
145+
htlc_maximum_msat: default_htlc_maximum_msat,
151146
fee_base_msat: default_fee_base_msat,
152147
fee_proportional_millionths: default_fee_proportional_millionths,
153148
excess_data: vec![],
@@ -170,21 +165,14 @@ impl<NG: Deref<Target=NetworkGraph<L>>, L: Deref> RapidGossipSync<NG, L> where L
170165
action: ErrorAction::IgnoreError,
171166
})?;
172167

173-
let htlc_maximum_msat =
174-
if let Some(htlc_maximum_msat) = directional_info.htlc_maximum_msat {
175-
OptionalField::Present(htlc_maximum_msat)
176-
} else {
177-
OptionalField::Absent
178-
};
179-
180168
UnsignedChannelUpdate {
181169
chain_hash,
182170
short_channel_id,
183171
timestamp: backdated_timestamp,
184172
flags: standard_channel_flags,
185173
cltv_expiry_delta: directional_info.cltv_expiry_delta,
186174
htlc_minimum_msat: directional_info.htlc_minimum_msat,
187-
htlc_maximum_msat,
175+
htlc_maximum_msat: directional_info.htlc_maximum_msat,
188176
fee_base_msat: directional_info.fees.base_msat,
189177
fee_proportional_millionths: directional_info.fees.proportional_millionths,
190178
excess_data: vec![],
@@ -212,13 +200,8 @@ impl<NG: Deref<Target=NetworkGraph<L>>, L: Deref> RapidGossipSync<NG, L> where L
212200
}
213201

214202
if channel_flags & 0b_0000_0100 > 0 {
215-
let tentative_htlc_maximum_msat: u64 = Readable::read(read_cursor)?;
216-
synthetic_update.htlc_maximum_msat = if tentative_htlc_maximum_msat == u64::max_value()
217-
{
218-
OptionalField::Absent
219-
} else {
220-
OptionalField::Present(tentative_htlc_maximum_msat)
221-
};
203+
let htlc_maximum_msat: u64 = Readable::read(read_cursor)?;
204+
synthetic_update.htlc_maximum_msat = htlc_maximum_msat;
222205
}
223206

224207
network_graph.update_channel_unsigned(&synthetic_update)?;

lightning/src/ln/channel.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -6572,7 +6572,7 @@ mod tests {
65726572
use ln::channel::{Channel, InboundHTLCOutput, OutboundHTLCOutput, InboundHTLCState, OutboundHTLCState, HTLCCandidate, HTLCInitiator};
65736573
use ln::channel::{MAX_FUNDING_SATOSHIS_NO_WUMBO, TOTAL_BITCOIN_SUPPLY_SATOSHIS};
65746574
use ln::features::{InitFeatures, ChannelTypeFeatures};
6575-
use ln::msgs::{ChannelUpdate, DataLossProtect, DecodeError, OptionalField, UnsignedChannelUpdate};
6575+
use ln::msgs::{ChannelUpdate, DataLossProtect, DecodeError, OptionalField, UnsignedChannelUpdate, MAX_VALUE_MSAT};
65766576
use ln::script::ShutdownScript;
65776577
use ln::chan_utils;
65786578
use ln::chan_utils::{htlc_success_tx_weight, htlc_timeout_tx_weight};
@@ -6988,7 +6988,7 @@ mod tests {
69886988
flags: 0,
69896989
cltv_expiry_delta: 100,
69906990
htlc_minimum_msat: 5,
6991-
htlc_maximum_msat: OptionalField::Absent,
6991+
htlc_maximum_msat: MAX_VALUE_MSAT,
69926992
fee_base_msat: 110,
69936993
fee_proportional_millionths: 11,
69946994
excess_data: Vec::new(),

lightning/src/ln/channelmanager.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ use routing::router::{PaymentParameters, Route, RouteHop, RoutePath, RouteParame
4848
use ln::msgs;
4949
use ln::msgs::NetAddress;
5050
use ln::onion_utils;
51-
use ln::msgs::{ChannelMessageHandler, DecodeError, LightningError, MAX_VALUE_MSAT, OptionalField};
51+
use ln::msgs::{ChannelMessageHandler, DecodeError, LightningError, MAX_VALUE_MSAT};
5252
use ln::wire::Encode;
5353
use chain::keysinterface::{Sign, KeysInterface, KeysManager, InMemorySigner, Recipient};
5454
use util::config::{UserConfig, ChannelConfig};
@@ -2397,7 +2397,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
23972397
flags: (!were_node_one) as u8 | ((!chan.is_live() as u8) << 1),
23982398
cltv_expiry_delta: chan.get_cltv_expiry_delta(),
23992399
htlc_minimum_msat: chan.get_counterparty_htlc_minimum_msat(),
2400-
htlc_maximum_msat: OptionalField::Present(chan.get_announced_htlc_max_msat()),
2400+
htlc_maximum_msat: chan.get_announced_htlc_max_msat(),
24012401
fee_base_msat: chan.get_outbound_forwarding_fee_base_msat(),
24022402
fee_proportional_millionths: chan.get_fee_proportional_millionths(),
24032403
excess_data: Vec::new(),

lightning/src/ln/functional_tests.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use routing::gossip::NetworkGraph;
2828
use routing::router::{PaymentParameters, Route, RouteHop, RouteParameters, find_route, get_route};
2929
use ln::features::{ChannelFeatures, InitFeatures, InvoiceFeatures, NodeFeatures};
3030
use ln::msgs;
31-
use ln::msgs::{ChannelMessageHandler, RoutingMessageHandler, OptionalField, ErrorAction};
31+
use ln::msgs::{ChannelMessageHandler, RoutingMessageHandler, ErrorAction};
3232
use util::enforcing_trait_impls::EnforcingSigner;
3333
use util::{byte_utils, test_utils};
3434
use util::events::{Event, MessageSendEvent, MessageSendEventsProvider, PaymentPurpose, ClosureReason};
@@ -8312,19 +8312,19 @@ fn test_channel_update_has_correct_htlc_maximum_msat() {
83128312

83138313
// Assert that `node[0]`'s `ChannelUpdate` is capped at 50 percent of the `channel_value`, as
83148314
// that's the value of `node[1]`'s `holder_max_htlc_value_in_flight_msat`.
8315-
assert_eq!(node_0_chan_update.contents.htlc_maximum_msat, OptionalField::Present(channel_value_50_percent_msat));
8315+
assert_eq!(node_0_chan_update.contents.htlc_maximum_msat, channel_value_50_percent_msat);
83168316
// Assert that `node[1]`'s `ChannelUpdate` is capped at 30 percent of the `channel_value`, as
83178317
// that's the value of `node[0]`'s `holder_max_htlc_value_in_flight_msat`.
8318-
assert_eq!(node_1_chan_update.contents.htlc_maximum_msat, OptionalField::Present(channel_value_30_percent_msat));
8318+
assert_eq!(node_1_chan_update.contents.htlc_maximum_msat, channel_value_30_percent_msat);
83198319

83208320
// Assert that `node[2]`'s `ChannelUpdate` is capped at 90 percent of the `channel_value`, as
83218321
// the value of `node[3]`'s `holder_max_htlc_value_in_flight_msat` (100%), exceeds 90% of the
83228322
// `channel_value`.
8323-
assert_eq!(node_2_chan_update.contents.htlc_maximum_msat, OptionalField::Present(channel_value_90_percent_msat));
8323+
assert_eq!(node_2_chan_update.contents.htlc_maximum_msat, channel_value_90_percent_msat);
83248324
// Assert that `node[3]`'s `ChannelUpdate` is capped at 90 percent of the `channel_value`, as
83258325
// the value of `node[2]`'s `holder_max_htlc_value_in_flight_msat` (95%), exceeds 90% of the
83268326
// `channel_value`.
8327-
assert_eq!(node_3_chan_update.contents.htlc_maximum_msat, OptionalField::Present(channel_value_90_percent_msat));
8327+
assert_eq!(node_3_chan_update.contents.htlc_maximum_msat, channel_value_90_percent_msat);
83288328
}
83298329

83308330
#[test]

lightning/src/ln/msgs.rs

+19-31
Original file line numberDiff line numberDiff line change
@@ -647,8 +647,8 @@ pub struct UnsignedChannelUpdate {
647647
pub cltv_expiry_delta: u16,
648648
/// The minimum HTLC size incoming to sender, in milli-satoshi
649649
pub htlc_minimum_msat: u64,
650-
/// Optionally, the maximum HTLC value incoming to sender, in milli-satoshi
651-
pub htlc_maximum_msat: OptionalField<u64>,
650+
/// The maximum HTLC value incoming to sender, in milli-satoshi. Used to be optional.
651+
pub htlc_maximum_msat: u64,
652652
/// The base HTLC fee charged by sender, in milli-satoshi
653653
pub fee_base_msat: u32,
654654
/// The amount to fee multiplier, in micro-satoshi
@@ -1514,14 +1514,12 @@ impl_writeable!(ChannelAnnouncement, {
15141514

15151515
impl Writeable for UnsignedChannelUpdate {
15161516
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
1517-
let mut message_flags: u8 = 0;
1518-
if let OptionalField::Present(_) = self.htlc_maximum_msat {
1519-
message_flags = 1;
1520-
}
1517+
// `message_flags` used to indicate presence of `htlc_maximum_msat`, but was deprecated in the spec.
1518+
const MESSAGE_FLAGS: u8 = 1;
15211519
self.chain_hash.write(w)?;
15221520
self.short_channel_id.write(w)?;
15231521
self.timestamp.write(w)?;
1524-
let all_flags = self.flags as u16 | ((message_flags as u16) << 8);
1522+
let all_flags = self.flags as u16 | ((MESSAGE_FLAGS as u16) << 8);
15251523
all_flags.write(w)?;
15261524
self.cltv_expiry_delta.write(w)?;
15271525
self.htlc_minimum_msat.write(w)?;
@@ -1535,22 +1533,20 @@ impl Writeable for UnsignedChannelUpdate {
15351533

15361534
impl Readable for UnsignedChannelUpdate {
15371535
fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
1538-
let has_htlc_maximum_msat;
15391536
Ok(Self {
15401537
chain_hash: Readable::read(r)?,
15411538
short_channel_id: Readable::read(r)?,
15421539
timestamp: Readable::read(r)?,
15431540
flags: {
15441541
let flags: u16 = Readable::read(r)?;
1545-
let message_flags = flags >> 8;
1546-
has_htlc_maximum_msat = (message_flags as i32 & 1) == 1;
1542+
// Note: we ignore the `message_flags` for now, since it was deprecated by the spec.
15471543
flags as u8
15481544
},
15491545
cltv_expiry_delta: Readable::read(r)?,
15501546
htlc_minimum_msat: Readable::read(r)?,
15511547
fee_base_msat: Readable::read(r)?,
15521548
fee_proportional_millionths: Readable::read(r)?,
1553-
htlc_maximum_msat: if has_htlc_maximum_msat { Readable::read(r)? } else { OptionalField::Absent },
1549+
htlc_maximum_msat: Readable::read(r)?,
15541550
excess_data: read_to_end(r)?,
15551551
})
15561552
}
@@ -2103,7 +2099,7 @@ mod tests {
21032099
do_encoding_node_announcement(false, false, true, false, true, false, false, false);
21042100
}
21052101

2106-
fn do_encoding_channel_update(direction: bool, disable: bool, htlc_maximum_msat: bool, excess_data: bool) {
2102+
fn do_encoding_channel_update(direction: bool, disable: bool, excess_data: bool) {
21072103
let secp_ctx = Secp256k1::new();
21082104
let (privkey_1, _) = get_keys_from!("0101010101010101010101010101010101010101010101010101010101010101", secp_ctx);
21092105
let sig_1 = get_sig_on!(privkey_1, secp_ctx, String::from("01010101010101010101010101010101"));
@@ -2114,7 +2110,7 @@ mod tests {
21142110
flags: if direction { 1 } else { 0 } | if disable { 1 << 1 } else { 0 },
21152111
cltv_expiry_delta: 144,
21162112
htlc_minimum_msat: 1000000,
2117-
htlc_maximum_msat: if htlc_maximum_msat { OptionalField::Present(131355275467161) } else { OptionalField::Absent },
2113+
htlc_maximum_msat: 131355275467161,
21182114
fee_base_msat: 10000,
21192115
fee_proportional_millionths: 20,
21202116
excess_data: if excess_data { vec![0, 0, 0, 0, 59, 154, 202, 0] } else { Vec::new() }
@@ -2127,11 +2123,7 @@ mod tests {
21272123
let mut target_value = hex::decode("d977cb9b53d93a6ff64bb5f1e158b4094b66e798fb12911168a3ccdf80a83096340a6a95da0ae8d9f776528eecdbb747eb6b545495a4319ed5378e35b21e073a").unwrap();
21282124
target_value.append(&mut hex::decode("000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f").unwrap());
21292125
target_value.append(&mut hex::decode("00083a840000034d013413a7").unwrap());
2130-
if htlc_maximum_msat {
2131-
target_value.append(&mut hex::decode("01").unwrap());
2132-
} else {
2133-
target_value.append(&mut hex::decode("00").unwrap());
2134-
}
2126+
target_value.append(&mut hex::decode("01").unwrap());
21352127
target_value.append(&mut hex::decode("00").unwrap());
21362128
if direction {
21372129
let flag = target_value.last_mut().unwrap();
@@ -2142,9 +2134,7 @@ mod tests {
21422134
*flag = *flag | 1 << 1;
21432135
}
21442136
target_value.append(&mut hex::decode("009000000000000f42400000271000000014").unwrap());
2145-
if htlc_maximum_msat {
2146-
target_value.append(&mut hex::decode("0000777788889999").unwrap());
2147-
}
2137+
target_value.append(&mut hex::decode("0000777788889999").unwrap());
21482138
if excess_data {
21492139
target_value.append(&mut hex::decode("000000003b9aca00").unwrap());
21502140
}
@@ -2153,16 +2143,14 @@ mod tests {
21532143

21542144
#[test]
21552145
fn encoding_channel_update() {
2156-
do_encoding_channel_update(false, false, false, false);
2157-
do_encoding_channel_update(false, false, false, true);
2158-
do_encoding_channel_update(true, false, false, false);
2159-
do_encoding_channel_update(true, false, false, true);
2160-
do_encoding_channel_update(false, true, false, false);
2161-
do_encoding_channel_update(false, true, false, true);
2162-
do_encoding_channel_update(false, false, true, false);
2163-
do_encoding_channel_update(false, false, true, true);
2164-
do_encoding_channel_update(true, true, true, false);
2165-
do_encoding_channel_update(true, true, true, true);
2146+
do_encoding_channel_update(false, false, false);
2147+
do_encoding_channel_update(false, false, true);
2148+
do_encoding_channel_update(true, false, false);
2149+
do_encoding_channel_update(true, false, true);
2150+
do_encoding_channel_update(false, true, false);
2151+
do_encoding_channel_update(false, true, true);
2152+
do_encoding_channel_update(true, true, false);
2153+
do_encoding_channel_update(true, true, true);
21662154
}
21672155

21682156
fn do_encoding_open_channel(random_bit: bool, shutdown: bool, incl_chan_type: bool) {

lightning/src/ln/onion_route_tests.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use routing::gossip::{NetworkUpdate, RoutingFees, NodeId};
2121
use routing::router::{get_route, PaymentParameters, Route, RouteHint, RouteHintHop};
2222
use ln::features::{InitFeatures, InvoiceFeatures, NodeFeatures};
2323
use ln::msgs;
24-
use ln::msgs::{ChannelMessageHandler, ChannelUpdate, OptionalField};
24+
use ln::msgs::{ChannelMessageHandler, ChannelUpdate};
2525
use ln::wire::Encode;
2626
use util::events::{Event, MessageSendEvent, MessageSendEventsProvider};
2727
use util::ser::{ReadableArgs, Writeable, Writer};
@@ -227,7 +227,7 @@ impl msgs::ChannelUpdate {
227227
flags: 0,
228228
cltv_expiry_delta: 0,
229229
htlc_minimum_msat: 0,
230-
htlc_maximum_msat: OptionalField::Absent,
230+
htlc_maximum_msat: msgs::MAX_VALUE_MSAT,
231231
fee_base_msat: 0,
232232
fee_proportional_millionths: 0,
233233
excess_data: vec![],

lightning/src/ln/priv_short_conf_tests.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use routing::gossip::RoutingFees;
1919
use routing::router::{PaymentParameters, RouteHint, RouteHintHop};
2020
use ln::features::{InitFeatures, InvoiceFeatures, ChannelTypeFeatures};
2121
use ln::msgs;
22-
use ln::msgs::{ChannelMessageHandler, RoutingMessageHandler, OptionalField, ChannelUpdate, ErrorAction};
22+
use ln::msgs::{ChannelMessageHandler, RoutingMessageHandler, ChannelUpdate, ErrorAction};
2323
use ln::wire::Encode;
2424
use util::enforcing_trait_impls::EnforcingSigner;
2525
use util::events::{ClosureReason, Event, MessageSendEvent, MessageSendEventsProvider};
@@ -523,7 +523,7 @@ fn test_scid_alias_returned() {
523523
flags: 1,
524524
cltv_expiry_delta: accept_forward_cfg.channel_config.cltv_expiry_delta,
525525
htlc_minimum_msat: 1_000,
526-
htlc_maximum_msat: OptionalField::Present(1_000_000), // Defaults to 10% of the channel value
526+
htlc_maximum_msat: 1_000_000, // Defaults to 10% of the channel value
527527
fee_base_msat: last_hop[0].counterparty.forwarding_info.as_ref().unwrap().fee_base_msat,
528528
fee_proportional_millionths: last_hop[0].counterparty.forwarding_info.as_ref().unwrap().fee_proportional_millionths,
529529
excess_data: Vec::new(),

0 commit comments

Comments
 (0)