Skip to content

Commit 1b6093f

Browse files
author
Antoine Riard
committed
Track remote peer forwarding parameters for local channel
1 parent 33553d7 commit 1b6093f

File tree

8 files changed

+109
-1
lines changed

8 files changed

+109
-1
lines changed

fuzz/fuzz_targets/router_target.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,10 @@ pub fn do_test(data: &[u8]) {
206206
remote_network_id: get_pubkey!(),
207207
channel_value_satoshis: slice_to_be64(get_slice!(8)),
208208
user_id: 0,
209+
their_cltv_expiry_delta: 0,
210+
their_htlc_minimum_msat: 0,
211+
their_fee_base_msat: 0,
212+
their_fee_proportional_millionths: 0,
209213
});
210214
}
211215
Some(&first_hops_vec[..])

src/ln/channel.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,9 @@ pub(super) struct Channel {
325325
their_to_self_delay: u16,
326326
//implied by BREAKDOWN_TIMEOUT: our_to_self_delay: u16,
327327
their_max_accepted_htlcs: u16,
328+
their_cltv_expiry_delta: u16,
329+
their_fee_base_msat: u32,
330+
their_fee_proportional_millionths: u32,
328331
//implied by OUR_MAX_HTLCS: our_max_accepted_htlcs: u16,
329332
minimum_depth: u32,
330333

@@ -491,6 +494,9 @@ impl Channel {
491494
our_htlc_minimum_msat: Channel::derive_our_htlc_minimum_msat(feerate),
492495
their_to_self_delay: 0,
493496
their_max_accepted_htlcs: 0,
497+
their_cltv_expiry_delta: 0,
498+
their_fee_base_msat: 0,
499+
their_fee_proportional_millionths: 0,
494500
minimum_depth: 0, // Filled in in accept_channel
495501

496502
their_funding_pubkey: None,
@@ -681,6 +687,9 @@ impl Channel {
681687
our_htlc_minimum_msat: Channel::derive_our_htlc_minimum_msat(msg.feerate_per_kw as u64),
682688
their_to_self_delay: msg.to_self_delay,
683689
their_max_accepted_htlcs: msg.max_accepted_htlcs,
690+
their_cltv_expiry_delta: 0,
691+
their_fee_base_msat: 0,
692+
their_fee_proportional_millionths: 0,
684693
minimum_depth: Channel::derive_minimum_depth(msg.funding_satoshis*1000, msg.push_msat),
685694

686695
their_funding_pubkey: Some(msg.funding_pubkey),
@@ -2040,6 +2049,20 @@ impl Channel {
20402049

20412050
}
20422051

2052+
/// Set channel fields with remote peer forwarding parameters, used mainly by ChannelDetails to feed the Router
2053+
/// If remote peer set htlc_minimum_msat to full channel value, we reject the whole update and close channel
2054+
pub fn channel_update(&mut self, msg: &msgs::ChannelUpdate) -> Result<(), ChannelError> {
2055+
if msg.contents.htlc_minimum_msat >= (self.channel_value_satoshis - self.their_channel_reserve_satoshis) * 1000 {
2056+
return Err(ChannelError::Close("Minimum htlc value is full channel value"));
2057+
}
2058+
self.their_cltv_expiry_delta = msg.contents.cltv_expiry_delta;
2059+
self.their_htlc_minimum_msat = msg.contents.htlc_minimum_msat;
2060+
self.their_fee_base_msat = msg.contents.fee_base_msat;
2061+
self.their_fee_proportional_millionths = msg.contents.fee_proportional_millionths;
2062+
2063+
Ok(())
2064+
}
2065+
20432066
/// Adds a pending update to this channel. See the doc for send_htlc for
20442067
/// further details on the optionness of the return value.
20452068
/// You MUST call send_commitment prior to any other calls on this Channel
@@ -2641,6 +2664,18 @@ impl Channel {
26412664
self.our_htlc_minimum_msat
26422665
}
26432666

2667+
pub fn get_their_cltv_expiry_delta(&self) -> u16 {
2668+
self.their_cltv_expiry_delta
2669+
}
2670+
2671+
pub fn get_their_fee_base_msat(&self) -> u32 {
2672+
self.their_fee_base_msat
2673+
}
2674+
2675+
pub fn get_their_fee_proportional_millionths(&self) -> u32 {
2676+
self.their_fee_proportional_millionths
2677+
}
2678+
26442679
pub fn get_value_satoshis(&self) -> u64 {
26452680
self.channel_value_satoshis
26462681
}
@@ -3587,6 +3622,9 @@ impl Writeable for Channel {
35873622
self.our_htlc_minimum_msat.write(writer)?;
35883623
self.their_to_self_delay.write(writer)?;
35893624
self.their_max_accepted_htlcs.write(writer)?;
3625+
self.their_cltv_expiry_delta.write(writer)?;
3626+
self.their_fee_base_msat.write(writer)?;
3627+
self.their_fee_proportional_millionths.write(writer)?;
35903628
self.minimum_depth.write(writer)?;
35913629

35923630
write_option!(self.their_funding_pubkey);
@@ -3761,6 +3799,9 @@ impl<R : ::std::io::Read> ReadableArgs<R, Arc<Logger>> for Channel {
37613799
let our_htlc_minimum_msat = Readable::read(reader)?;
37623800
let their_to_self_delay = Readable::read(reader)?;
37633801
let their_max_accepted_htlcs = Readable::read(reader)?;
3802+
let their_cltv_expiry_delta = Readable::read(reader)?;
3803+
let their_fee_base_msat = Readable::read(reader)?;
3804+
let their_fee_proportional_millionths = Readable::read(reader)?;
37643805
let minimum_depth = Readable::read(reader)?;
37653806

37663807
let their_funding_pubkey = read_option!();
@@ -3838,6 +3879,9 @@ impl<R : ::std::io::Read> ReadableArgs<R, Arc<Logger>> for Channel {
38383879
our_htlc_minimum_msat,
38393880
their_to_self_delay,
38403881
their_max_accepted_htlcs,
3882+
their_cltv_expiry_delta,
3883+
their_fee_base_msat,
3884+
their_fee_proportional_millionths,
38413885
minimum_depth,
38423886

38433887
their_funding_pubkey,

src/ln/channelmanager.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,14 @@ pub struct ChannelDetails {
384384
pub channel_value_satoshis: u64,
385385
/// The user_id passed in to create_channel, or 0 if the channel was inbound.
386386
pub user_id: u64,
387+
/// The CLTV delta subtracted by the remote peer as a forwarding node to any incoming HTLC's cltv_expiry
388+
pub their_cltv_expiry_delta: u16,
389+
/// The minimum HTLC amount for which the remote peer as a forwarding node is ready to relay
390+
pub their_htlc_minimum_msat: u64,
391+
/// The base fee the remote peer as a forwarding node will take to relay any HTLC.
392+
pub their_fee_base_msat: u32,
393+
/// The proportional fee on amount forwarded by a HTLC the remote peer will take to relay.
394+
pub their_fee_proportional_millionths: u32,
387395
}
388396

389397
macro_rules! handle_error {
@@ -539,6 +547,10 @@ impl ChannelManager {
539547
remote_network_id: channel.get_their_node_id(),
540548
channel_value_satoshis: channel.get_value_satoshis(),
541549
user_id: channel.get_user_id(),
550+
their_cltv_expiry_delta: channel.get_their_cltv_expiry_delta(),
551+
their_htlc_minimum_msat: channel.get_their_htlc_minimum_msat(),
552+
their_fee_base_msat: channel.get_their_fee_base_msat(),
553+
their_fee_proportional_millionths: channel.get_their_fee_proportional_millionths(),
542554
});
543555
}
544556
res
@@ -560,6 +572,10 @@ impl ChannelManager {
560572
remote_network_id: channel.get_their_node_id(),
561573
channel_value_satoshis: channel.get_value_satoshis(),
562574
user_id: channel.get_user_id(),
575+
their_cltv_expiry_delta: channel.get_their_cltv_expiry_delta(),
576+
their_htlc_minimum_msat: channel.get_their_htlc_minimum_msat(),
577+
their_fee_base_msat: channel.get_their_fee_base_msat(),
578+
their_fee_proportional_millionths: channel.get_their_fee_proportional_millionths(),
563579
});
564580
}
565581
}
@@ -2444,6 +2460,29 @@ impl ChannelManager {
24442460
Ok(())
24452461
}
24462462

2463+
fn internal_channel_update(&self, their_node_id: &PublicKey, msg: &msgs::ChannelUpdate) -> Result<(), MsgHandleErrInternal> {
2464+
let mut channel_state_lock = self.channel_state.lock().unwrap();
2465+
let channel_state = channel_state_lock.borrow_parts();
2466+
let chan_id = match channel_state.short_to_id.get(&msg.contents.short_channel_id) {
2467+
Some(chan_id) => chan_id.clone(),
2468+
None => {
2469+
// It's not a local channel
2470+
return Ok(())
2471+
}
2472+
};
2473+
match channel_state.by_id.entry(chan_id) {
2474+
hash_map::Entry::Occupied(mut chan) => {
2475+
if chan.get().get_their_node_id() != *their_node_id {
2476+
//TODO: see issue #153, need a consistent behavior on obnoxious behavior from random node
2477+
return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!", chan_id));
2478+
}
2479+
try_chan_entry!(self, chan.get_mut().channel_update(&msg), channel_state, chan);
2480+
},
2481+
hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel", chan_id))
2482+
}
2483+
Ok(())
2484+
}
2485+
24472486
fn internal_channel_reestablish(&self, their_node_id: &PublicKey, msg: &msgs::ChannelReestablish) -> Result<(), MsgHandleErrInternal> {
24482487
let mut channel_state_lock = self.channel_state.lock().unwrap();
24492488
let channel_state = channel_state_lock.borrow_parts();
@@ -2776,6 +2815,11 @@ impl ChannelMessageHandler for ChannelManager {
27762815
handle_error!(self, self.internal_announcement_signatures(their_node_id, msg), their_node_id)
27772816
}
27782817

2818+
fn handle_channel_update(&self, their_node_id: &PublicKey, msg: &msgs::ChannelUpdate) -> Result<(), HandleError> {
2819+
let _ = self.total_consistency_lock.read().unwrap();
2820+
handle_error!(self, self.internal_channel_update(their_node_id, msg), their_node_id)
2821+
}
2822+
27792823
fn handle_channel_reestablish(&self, their_node_id: &PublicKey, msg: &msgs::ChannelReestablish) -> Result<(), HandleError> {
27802824
let _ = self.total_consistency_lock.read().unwrap();
27812825
handle_error!(self, self.internal_channel_reestablish(their_node_id, msg), their_node_id)

src/ln/msgs.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -559,6 +559,8 @@ pub trait ChannelMessageHandler : events::MessageSendEventsProvider + Send + Syn
559559
// Channel-to-announce:
560560
/// Handle an incoming announcement_signatures message from the given peer.
561561
fn handle_announcement_signatures(&self, their_node_id: &PublicKey, msg: &AnnouncementSignatures) -> Result<(), HandleError>;
562+
/// Handle an incoming channel_update message from the given peer.
563+
fn handle_channel_update(&self, their_node_id: &PublicKey, msg: &ChannelUpdate) -> Result<(), HandleError>;
562564

563565
// Connection loss/reestablish:
564566
/// Indicates a connection to the peer failed/an existing connection was lost. If no connection

src/ln/peer_handler.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -739,6 +739,7 @@ impl<Descriptor: SocketDescriptor> PeerManager<Descriptor> {
739739
},
740740
258 => {
741741
let msg = try_potential_decodeerror!(msgs::ChannelUpdate::read(&mut reader));
742+
try_potential_handleerror!(self.message_handler.chan_handler.handle_channel_update(&peer.their_node_id.unwrap(), &msg));
742743
let should_forward = try_potential_handleerror!(self.message_handler.route_handler.handle_channel_update(&msg));
743744

744745
if should_forward {

src/ln/router.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1292,6 +1292,10 @@ mod tests {
12921292
remote_network_id: node8.clone(),
12931293
channel_value_satoshis: 0,
12941294
user_id: 0,
1295+
their_cltv_expiry_delta: 0,
1296+
their_htlc_minimum_msat: 0,
1297+
their_fee_base_msat: 0,
1298+
their_fee_proportional_millionths: 0,
12951299
}];
12961300
let route = router.get_route(&node3, Some(&our_chans), &Vec::new(), 100, 42).unwrap();
12971301
assert_eq!(route.hops.len(), 2);
@@ -1367,6 +1371,10 @@ mod tests {
13671371
remote_network_id: node4.clone(),
13681372
channel_value_satoshis: 0,
13691373
user_id: 0,
1374+
their_cltv_expiry_delta: 0,
1375+
their_htlc_minimum_msat: 0,
1376+
their_fee_base_msat: 0,
1377+
their_fee_proportional_millionths: 0,
13701378
}];
13711379
let route = router.get_route(&node7, Some(&our_chans), &last_hops, 100, 42).unwrap();
13721380
assert_eq!(route.hops.len(), 2);

src/util/config.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ pub struct ChannelHandshakeLimits {
3131
/// only applies to inbound channels.
3232
pub min_funding_satoshis: u64,
3333
/// The remote node sets a limit on the minimum size of HTLCs we can send to them. This allows
34-
/// you to limit the maximum minimum-size they can require.
34+
/// you to limit the maximum minimum-size they can require. Remote node may increase its
35+
/// htlc_minimum_msat beyond limits with a channel_update msg, as it's equivalent to them
36+
/// just rejecting all HTLCs we can't enforce it.
3537
pub max_htlc_minimum_msat: u64,
3638
/// The remote node sets a limit on the maximum value of pending HTLCs to them at any given
3739
/// time to limit their funds exposure to HTLCs. This allows you to set a minimum such value.

src/util/test_utils.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,9 @@ impl msgs::ChannelMessageHandler for TestChannelMessageHandler {
133133
fn handle_announcement_signatures(&self, _their_node_id: &PublicKey, _msg: &msgs::AnnouncementSignatures) -> Result<(), HandleError> {
134134
Err(HandleError { err: "", action: None })
135135
}
136+
fn handle_channel_update(&self, _their_node_id: &PublicKey, _msg: &msgs::ChannelUpdate) -> Result<(), HandleError> {
137+
Err(HandleError { err: "", action: None })
138+
}
136139
fn handle_channel_reestablish(&self, _their_node_id: &PublicKey, _msg: &msgs::ChannelReestablish) -> Result<(), HandleError> {
137140
Err(HandleError { err: "", action: None })
138141
}

0 commit comments

Comments
 (0)