Skip to content

Commit 920d145

Browse files
yuntaiTheBlueMatt
authored andcommitted
Move HTLCFailChannelUpdate handling out-of-band
While this isn't neccessary for message ordering consistency, this does mean that we won't end up processing an HTLCFailChannelUpdate from a update_fail_htlc prior to it being fully committed (where if the peer disconnects/reconnects it could theoretically give us a different result, eg if their next-hop reconnected to them).
1 parent dc61c98 commit 920d145

File tree

5 files changed

+42
-27
lines changed

5 files changed

+42
-27
lines changed

src/ln/channelmanager.rs

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1381,11 +1381,21 @@ impl ChannelManager {
13811381
match source {
13821382
HTLCSource::OutboundRoute { .. } => {
13831383
mem::drop(channel_state);
1384-
1385-
let mut pending_events = self.pending_events.lock().unwrap();
1386-
pending_events.push(events::Event::PaymentFailed {
1387-
payment_hash: payment_hash.clone()
1388-
});
1384+
if let &HTLCFailReason::ErrorPacket { ref err } = &onion_error {
1385+
let (channel_update, payment_retryable) = self.process_onion_failure(&source, err.data.clone());
1386+
let mut pending_events = self.pending_events.lock().unwrap();
1387+
if let Some(channel_update) = channel_update {
1388+
pending_events.push(events::Event::PaymentFailureNetworkUpdate {
1389+
update: channel_update,
1390+
});
1391+
}
1392+
pending_events.push(events::Event::PaymentFailed {
1393+
payment_hash: payment_hash.clone(),
1394+
rejected_by_dest: !payment_retryable,
1395+
});
1396+
} else {
1397+
panic!("should have onion error packet here");
1398+
}
13891399
},
13901400
HTLCSource::PreviousHopData(HTLCPreviousHopData { short_channel_id, htlc_id, incoming_packet_shared_secret }) => {
13911401
let err_packet = match onion_error {
@@ -1996,9 +2006,9 @@ impl ChannelManager {
19962006
} else { ((None, true)) }
19972007
}
19982008

1999-
fn internal_update_fail_htlc(&self, their_node_id: &PublicKey, msg: &msgs::UpdateFailHTLC) -> Result<Option<msgs::HTLCFailChannelUpdate>, MsgHandleErrInternal> {
2009+
fn internal_update_fail_htlc(&self, their_node_id: &PublicKey, msg: &msgs::UpdateFailHTLC) -> Result<(), MsgHandleErrInternal> {
20002010
let mut channel_state = self.channel_state.lock().unwrap();
2001-
let htlc_source = match channel_state.by_id.get_mut(&msg.channel_id) {
2011+
match channel_state.by_id.get_mut(&msg.channel_id) {
20022012
Some(chan) => {
20032013
if chan.get_their_node_id() != *their_node_id {
20042014
//TODO: here and below MsgHandleErrInternal, #153 case
@@ -2009,17 +2019,7 @@ impl ChannelManager {
20092019
},
20102020
None => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel", msg.channel_id))
20112021
}?;
2012-
2013-
// we are the origin node and update route information
2014-
// also determine if the payment is retryable
2015-
if let &HTLCSource::OutboundRoute { .. } = htlc_source {
2016-
let (channel_update, _payment_retry) = self.process_onion_failure(htlc_source, msg.reason.data.clone());
2017-
Ok(channel_update)
2018-
// TODO: include pyament_retry info in PaymentFailed event that will be
2019-
// fired when receiving revoke_and_ack
2020-
} else {
2021-
Ok(None)
2022-
}
2022+
Ok(())
20232023
}
20242024

20252025
fn internal_update_fail_malformed_htlc(&self, their_node_id: &PublicKey, msg: &msgs::UpdateFailMalformedHTLC) -> Result<(), MsgHandleErrInternal> {
@@ -2424,7 +2424,7 @@ impl ChannelMessageHandler for ChannelManager {
24242424
handle_error!(self, self.internal_update_fulfill_htlc(their_node_id, msg), their_node_id)
24252425
}
24262426

2427-
fn handle_update_fail_htlc(&self, their_node_id: &PublicKey, msg: &msgs::UpdateFailHTLC) -> Result<Option<msgs::HTLCFailChannelUpdate>, HandleError> {
2427+
fn handle_update_fail_htlc(&self, their_node_id: &PublicKey, msg: &msgs::UpdateFailHTLC) -> Result<(), HandleError> {
24282428
handle_error!(self, self.internal_update_fail_htlc(their_node_id, msg), their_node_id)
24292429
}
24302430

@@ -3296,8 +3296,9 @@ mod tests {
32963296
let events = origin_node.node.get_and_clear_pending_events();
32973297
assert_eq!(events.len(), 1);
32983298
match events[0] {
3299-
Event::PaymentFailed { payment_hash } => {
3299+
Event::PaymentFailed { payment_hash, rejected_by_dest } => {
33003300
assert_eq!(payment_hash, our_payment_hash);
3301+
assert!(rejected_by_dest);
33013302
},
33023303
_ => panic!("Unexpected event"),
33033304
}
@@ -5064,8 +5065,9 @@ mod tests {
50645065
_ => panic!("Unexpected event"),
50655066
}
50665067
match events[1] {
5067-
Event::PaymentFailed { payment_hash } => {
5068+
Event::PaymentFailed { payment_hash, rejected_by_dest } => {
50685069
assert_eq!(payment_hash, payment_hash_5);
5070+
assert!(rejected_by_dest);
50695071
},
50705072
_ => panic!("Unexpected event"),
50715073
}

src/ln/msgs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -529,7 +529,7 @@ pub trait ChannelMessageHandler : events::EventsProvider + Send + Sync {
529529
/// Handle an incoming update_fulfill_htlc message from the given peer.
530530
fn handle_update_fulfill_htlc(&self, their_node_id: &PublicKey, msg: &UpdateFulfillHTLC) -> Result<(), HandleError>;
531531
/// Handle an incoming update_fail_htlc message from the given peer.
532-
fn handle_update_fail_htlc(&self, their_node_id: &PublicKey, msg: &UpdateFailHTLC) -> Result<Option<HTLCFailChannelUpdate>, HandleError>;
532+
fn handle_update_fail_htlc(&self, their_node_id: &PublicKey, msg: &UpdateFailHTLC) -> Result<(), HandleError>;
533533
/// Handle an incoming update_fail_malformed_htlc message from the given peer.
534534
fn handle_update_fail_malformed_htlc(&self, their_node_id: &PublicKey, msg: &UpdateFailMalformedHTLC) -> Result<(), HandleError>;
535535
/// Handle an incoming commitment_signed message from the given peer.

src/ln/peer_handler.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -615,10 +615,7 @@ impl<Descriptor: SocketDescriptor> PeerManager<Descriptor> {
615615
},
616616
131 => {
617617
let msg = try_potential_decodeerror!(msgs::UpdateFailHTLC::read(&mut reader));
618-
let chan_update = try_potential_handleerror!(self.message_handler.chan_handler.handle_update_fail_htlc(&peer.their_node_id.unwrap(), &msg));
619-
if let Some(update) = chan_update {
620-
self.message_handler.route_handler.handle_htlc_fail_channel_update(&update);
621-
}
618+
try_potential_handleerror!(self.message_handler.chan_handler.handle_update_fail_htlc(&peer.their_node_id.unwrap(), &msg));
622619
},
623620
135 => {
624621
let msg = try_potential_decodeerror!(msgs::UpdateFailMalformedHTLC::read(&mut reader));
@@ -906,6 +903,10 @@ impl<Descriptor: SocketDescriptor> PeerManager<Descriptor> {
906903
}
907904
continue;
908905
},
906+
Event::PaymentFailureNetworkUpdate { ref update } => {
907+
self.message_handler.route_handler.handle_htlc_fail_channel_update(update);
908+
continue;
909+
},
909910
Event::HandleError { ref node_id, ref action } => {
910911
if let Some(ref action) = *action {
911912
match *action {

src/util/events.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@ pub enum Event {
7575
PaymentFailed {
7676
/// The hash which was given to ChannelManager::send_payment.
7777
payment_hash: [u8; 32],
78+
/// Indicates the payment was rejected for some reason by the recipient. This implies that
79+
/// the payment has failed, not just the route in question. If this is not set, you may
80+
/// retry the payment via a different route.
81+
rejected_by_dest: bool,
7882
},
7983
/// Used to indicate that ChannelManager::process_pending_htlc_forwards should be called at a
8084
/// time in the future.
@@ -161,6 +165,14 @@ pub enum Event {
161165
node_id: PublicKey,
162166
/// The action which should be taken.
163167
action: Option<msgs::ErrorAction>
168+
},
169+
/// When a payment fails we may receive updates back from the hop where it failed. In such
170+
/// cases this event is generated so that we can inform the router of this information.
171+
///
172+
/// This event is handled by PeerManager::process_events if you are using a PeerManager.
173+
PaymentFailureNetworkUpdate {
174+
/// The channel/node update which should be sent to router
175+
update: msgs::HTLCFailChannelUpdate,
164176
}
165177
}
166178

src/util/test_utils.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ impl msgs::ChannelMessageHandler for TestChannelMessageHandler {
110110
fn handle_update_fulfill_htlc(&self, _their_node_id: &PublicKey, _msg: &msgs::UpdateFulfillHTLC) -> Result<(), HandleError> {
111111
Err(HandleError { err: "", action: None })
112112
}
113-
fn handle_update_fail_htlc(&self, _their_node_id: &PublicKey, _msg: &msgs::UpdateFailHTLC) -> Result<Option<msgs::HTLCFailChannelUpdate>, HandleError> {
113+
fn handle_update_fail_htlc(&self, _their_node_id: &PublicKey, _msg: &msgs::UpdateFailHTLC) -> Result<(), HandleError> {
114114
Err(HandleError { err: "", action: None })
115115
}
116116
fn handle_update_fail_malformed_htlc(&self, _their_node_id: &PublicKey, _msg: &msgs::UpdateFailMalformedHTLC) -> Result<(), HandleError> {

0 commit comments

Comments
 (0)