Skip to content

Commit ef4107a

Browse files
Enable htlc forwarding over substitute channels
Attempt to forward htlcs over alternative channels to the same peer, in case forwarding over the channel specified in the onion payload fails.
1 parent ae665ce commit ef4107a

File tree

1 file changed

+118
-66
lines changed

1 file changed

+118
-66
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 118 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -3081,9 +3081,36 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
30813081
if let Some(peer_state_mutex) = per_peer_state.get(&counterparty_node_id) {
30823082
let mut peer_state_lock = peer_state_mutex.lock().unwrap();
30833083
let peer_state = &mut *peer_state_lock;
3084-
if let hash_map::Entry::Occupied(mut chan) = peer_state.channel_by_id.entry(forward_chan_id) {
3085-
let mut add_htlc_msgs = Vec::new();
3086-
let mut fail_htlc_msgs = Vec::new();
3084+
if peer_state.channel_by_id.contains_key(&forward_chan_id) {
3085+
let mut htlcs_msgs_by_id: HashMap<[u8; 32], (Vec<msgs::UpdateAddHTLC>, Vec<msgs::UpdateFailHTLC>)> = HashMap::new();
3086+
3087+
macro_rules! add_channel_key {
3088+
($channel_id: expr) => {{
3089+
if !htlcs_msgs_by_id.contains_key(&$channel_id){
3090+
htlcs_msgs_by_id.insert($channel_id, (Vec::new(), Vec::new()));
3091+
}
3092+
}}
3093+
}
3094+
3095+
macro_rules! add_update_add_htlc {
3096+
($add_htlc_msg: expr, $channel_id: expr) => {{
3097+
add_channel_key!($channel_id);
3098+
if let hash_map::Entry::Occupied(mut entry) = htlcs_msgs_by_id.entry($channel_id) {
3099+
let msgs_entry = entry.get_mut();
3100+
msgs_entry.0.push($add_htlc_msg);
3101+
}
3102+
}}
3103+
}
3104+
3105+
macro_rules! add_update_fail_htlc {
3106+
($fail_htlc_msg: expr, $channel_id: expr) => {{
3107+
add_channel_key!($channel_id);
3108+
if let hash_map::Entry::Occupied(mut entry) = htlcs_msgs_by_id.entry($channel_id) {
3109+
let msgs_entry = entry.get_mut();
3110+
msgs_entry.1.push($fail_htlc_msg);
3111+
}
3112+
}}
3113+
}
30873114
for forward_info in pending_forwards.drain(..) {
30883115
match forward_info {
30893116
HTLCForwardInfo::AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info: PendingHTLCInfo {
@@ -3100,41 +3127,64 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
31003127
// Phantom payments are only PendingHTLCRouting::Receive.
31013128
phantom_shared_secret: None,
31023129
});
3103-
match chan.get_mut().send_htlc(amt_to_forward, payment_hash, outgoing_cltv_value, htlc_source.clone(), onion_packet, &self.logger) {
3104-
Err(e) => {
3105-
if let ChannelError::Ignore(msg) = e {
3106-
log_trace!(self.logger, "Failed to forward HTLC with payment_hash {}: {}", log_bytes!(payment_hash.0), msg);
3107-
} else {
3108-
panic!("Stated return value requirements in send_htlc() were not met");
3109-
}
3110-
let (failure_code, data) = self.get_htlc_temp_fail_err_and_data(0x1000|7, short_chan_id, chan.get());
3111-
failed_forwards.push((htlc_source, payment_hash,
3112-
HTLCFailReason::Reason { failure_code, data }
3113-
));
3114-
continue;
3115-
},
3116-
Ok(update_add) => {
3117-
match update_add {
3118-
Some(msg) => { add_htlc_msgs.push(msg); },
3119-
None => {
3120-
// Nothing to do here...we're waiting on a remote
3121-
// revoke_and_ack before we can add anymore HTLCs. The Channel
3122-
// will automatically handle building the update_add_htlc and
3123-
// commitment_signed messages when we can.
3124-
// TODO: Do some kind of timer to set the channel as !is_live()
3125-
// as we don't really want others relying on us relaying through
3126-
// this channel currently :/.
3130+
3131+
// Attempt to forward the HTLC over all available channels
3132+
// to the peer, but attempt to forward the HTLC over the
3133+
// channel specified in the onion payload first.
3134+
let mut counterparty_channel_ids = peer_state.channel_by_id.keys()
3135+
.filter(|chan_id| **chan_id != forward_chan_id)
3136+
.map(|chan_id| *chan_id).collect::<Vec<_>>();
3137+
counterparty_channel_ids.insert(0, forward_chan_id);
3138+
let mut send_succeeded = false;
3139+
for chan_id in counterparty_channel_ids {
3140+
match peer_state.channel_by_id.get_mut(&chan_id).unwrap().send_htlc(amt_to_forward, payment_hash, outgoing_cltv_value, htlc_source.clone(), onion_packet.clone(), &self.logger) {
3141+
Err(e) => {
3142+
if let ChannelError::Ignore(msg) = e {
3143+
log_trace!(
3144+
self.logger,
3145+
"Could not forward HTLC with payment_hash {}, over channel {} to peer {}. Will attempt to forward the HTLC over a substitute channel instead if possible. Reason: {}",
3146+
log_bytes!(payment_hash.0), log_bytes!(chan_id), counterparty_node_id, msg
3147+
);
3148+
} else {
3149+
panic!("Stated return value requirements in send_htlc() were not met");
3150+
}
3151+
},
3152+
Ok(update_add) => {
3153+
match update_add {
3154+
Some(msg) => {
3155+
log_info!(self.logger, "Will forward HTLC with payment_hash {}, over channel {}", log_bytes!(payment_hash.0), log_bytes!(chan_id));
3156+
add_update_add_htlc!(msg, chan_id);
3157+
},
3158+
None => {
3159+
// Nothing to do here...we're waiting on a remote
3160+
// revoke_and_ack before we can add anymore HTLCs. The Channel
3161+
// will automatically handle building the update_add_htlc and
3162+
// commitment_signed messages when we can.
3163+
// TODO: Do some kind of timer to set the channel as !is_live()
3164+
// as we don't really want others relying on us relaying through
3165+
// this channel currently :/.
3166+
}
31273167
}
3168+
send_succeeded = true;
3169+
break;
31283170
}
31293171
}
31303172
}
3173+
if !send_succeeded {
3174+
log_trace!(self.logger, "Failed to forward HTLC with payment_hash {} over all of the available channels to the peer", log_bytes!(payment_hash.0));
3175+
let (failure_code, data) = self.get_htlc_temp_fail_err_and_data(0x1000|7, short_chan_id, peer_state.channel_by_id.get(&forward_chan_id).unwrap());
3176+
failed_forwards.push((htlc_source, payment_hash,
3177+
HTLCFailReason::Reason { failure_code, data }
3178+
));
3179+
continue;
3180+
}
31313181
},
31323182
HTLCForwardInfo::AddHTLC { .. } => {
31333183
panic!("short_channel_id != 0 should imply any pending_forward entries are of type Forward");
31343184
},
31353185
HTLCForwardInfo::FailHTLC { htlc_id, err_packet } => {
31363186
log_trace!(self.logger, "Failing HTLC back to channel with short id {} (backward HTLC ID {}) after delay", short_chan_id, htlc_id);
3137-
match chan.get_mut().get_update_fail_htlc(htlc_id, err_packet, &self.logger) {
3187+
match peer_state.channel_by_id.get_mut(&forward_chan_id).unwrap().get_update_fail_htlc(htlc_id, err_packet, &self.logger) {
31383188
Err(e) => {
31393189
if let ChannelError::Ignore(msg) = e {
31403190
log_trace!(self.logger, "Failed to fail HTLC with ID {} backwards to short_id {}: {}", htlc_id, short_chan_id, msg);
@@ -3146,7 +3196,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
31463196
// the chain and sending the HTLC-Timeout is their problem.
31473197
continue;
31483198
},
3149-
Ok(Some(msg)) => { fail_htlc_msgs.push(msg); },
3199+
Ok(Some(msg)) => { add_update_fail_htlc!(msg, forward_chan_id); },
31503200
Ok(None) => {
31513201
// Nothing to do here...we're waiting on a remote
31523202
// revoke_and_ack before we can update the commitment
@@ -3162,46 +3212,48 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
31623212
}
31633213
}
31643214

3165-
if !add_htlc_msgs.is_empty() || !fail_htlc_msgs.is_empty() {
3166-
let (commitment_msg, monitor_update) = match chan.get_mut().send_commitment(&self.logger) {
3167-
Ok(res) => res,
3168-
Err(e) => {
3169-
// We surely failed send_commitment due to bad keys, in that case
3170-
// close channel and then send error message to peer.
3171-
let counterparty_node_id = chan.get().get_counterparty_node_id();
3172-
let err: Result<(), _> = match e {
3173-
ChannelError::Ignore(_) | ChannelError::Warn(_) => {
3174-
panic!("Stated return value requirements in send_commitment() were not met");
3175-
}
3176-
ChannelError::Close(msg) => {
3177-
log_trace!(self.logger, "Closing channel {} due to Close-required error: {}", log_bytes!(chan.key()[..]), msg);
3178-
let mut channel = remove_channel!(self, channel_state, chan);
3179-
// ChannelClosed event is generated by handle_error for us.
3180-
Err(MsgHandleErrInternal::from_finish_shutdown(msg, channel.channel_id(), channel.get_user_id(), channel.force_shutdown(true), self.get_channel_update_for_broadcast(&channel).ok()))
3181-
},
3182-
ChannelError::CloseDelayBroadcast(_) => { panic!("Wait is only generated on receipt of channel_reestablish, which is handled by try_chan_entry, we don't bother to support it here"); }
3183-
};
3184-
handle_errors.push((counterparty_node_id, err));
3215+
for (chan_id, (add_htlc_msgs, fail_htlc_msgs)) in htlcs_msgs_by_id.into_iter() {
3216+
if let hash_map::Entry::Occupied(mut chan) = peer_state.channel_by_id.entry(chan_id) {
3217+
let (commitment_msg, monitor_update) = match chan.get_mut().send_commitment(&self.logger) {
3218+
Ok(res) => res,
3219+
Err(e) => {
3220+
// We surely failed send_commitment due to bad keys, in that case
3221+
// close channel and then send error message to peer.
3222+
let counterparty_node_id = chan.get().get_counterparty_node_id();
3223+
let err: Result<(), _> = match e {
3224+
ChannelError::Ignore(_) | ChannelError::Warn(_) => {
3225+
panic!("Stated return value requirements in send_commitment() were not met");
3226+
}
3227+
ChannelError::Close(msg) => {
3228+
log_trace!(self.logger, "Closing channel {} due to Close-required error: {}", log_bytes!(chan.key()[..]), msg);
3229+
let mut channel = remove_channel!(self, channel_state, chan);
3230+
// ChannelClosed event is generated by handle_error for us.
3231+
Err(MsgHandleErrInternal::from_finish_shutdown(msg, channel.channel_id(), channel.get_user_id(), channel.force_shutdown(true), self.get_channel_update_for_broadcast(&channel).ok()))
3232+
},
3233+
ChannelError::CloseDelayBroadcast(_) => { panic!("Wait is only generated on receipt of channel_reestablish, which is handled by try_chan_entry, we don't bother to support it here"); }
3234+
};
3235+
handle_errors.push((counterparty_node_id, err));
3236+
continue;
3237+
}
3238+
};
3239+
if let Err(e) = self.chain_monitor.update_channel(chan.get().get_funding_txo().unwrap(), monitor_update) {
3240+
handle_errors.push((chan.get().get_counterparty_node_id(), handle_monitor_err!(self, e, channel_state, chan, RAACommitmentOrder::CommitmentFirst, false, true)));
31853241
continue;
31863242
}
3187-
};
3188-
if let Err(e) = self.chain_monitor.update_channel(chan.get().get_funding_txo().unwrap(), monitor_update) {
3189-
handle_errors.push((chan.get().get_counterparty_node_id(), handle_monitor_err!(self, e, channel_state, chan, RAACommitmentOrder::CommitmentFirst, false, true)));
3190-
continue;
3243+
log_debug!(self.logger, "Forwarding HTLCs resulted in a commitment update with {} HTLCs added and {} HTLCs failed for channel {}",
3244+
add_htlc_msgs.len(), fail_htlc_msgs.len(), log_bytes!(chan.get().channel_id()));
3245+
channel_state.pending_msg_events.push(events::MessageSendEvent::UpdateHTLCs {
3246+
node_id: chan.get().get_counterparty_node_id(),
3247+
updates: msgs::CommitmentUpdate {
3248+
update_add_htlcs: add_htlc_msgs,
3249+
update_fulfill_htlcs: Vec::new(),
3250+
update_fail_htlcs: fail_htlc_msgs,
3251+
update_fail_malformed_htlcs: Vec::new(),
3252+
update_fee: None,
3253+
commitment_signed: commitment_msg,
3254+
},
3255+
});
31913256
}
3192-
log_debug!(self.logger, "Forwarding HTLCs resulted in a commitment update with {} HTLCs added and {} HTLCs failed for channel {}",
3193-
add_htlc_msgs.len(), fail_htlc_msgs.len(), log_bytes!(chan.get().channel_id()));
3194-
channel_state.pending_msg_events.push(events::MessageSendEvent::UpdateHTLCs {
3195-
node_id: chan.get().get_counterparty_node_id(),
3196-
updates: msgs::CommitmentUpdate {
3197-
update_add_htlcs: add_htlc_msgs,
3198-
update_fulfill_htlcs: Vec::new(),
3199-
update_fail_htlcs: fail_htlc_msgs,
3200-
update_fail_malformed_htlcs: Vec::new(),
3201-
update_fee: None,
3202-
commitment_signed: commitment_msg,
3203-
},
3204-
});
32053257
}
32063258
} else {
32073259
let err = Err(MsgHandleErrInternal::send_err_msg_no_close(format!("No such channel for the counterparty_node_id {}, as indicated by the short_to_id map", counterparty_node_id), forward_chan_id));

0 commit comments

Comments
 (0)