Skip to content

Commit 358036d

Browse files
committed
Swap handle_monitor_update_fail for a macro ala try_chan_entry
This resolves an API bug where send_payment may return a MonitorUpdateFailed Err both when the payment will not be sent and when the HTLC will be retried automatically when monitor updating is restored. This makes it impossible for a client to know when they should retry a payment and when they should not.
1 parent 33553d7 commit 358036d

File tree

1 file changed

+65
-59
lines changed

1 file changed

+65
-59
lines changed

src/ln/channelmanager.rs

Lines changed: 65 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,24 @@ macro_rules! try_chan_entry {
442442
}
443443
}
444444

445+
// Does not break in case of TemporaryFailure!
446+
macro_rules! maybe_break_monitor_err {
447+
($self: expr, $err: expr, $channel_state: expr, $entry: expr, $action_type: path) => {
448+
match $err {
449+
ChannelMonitorUpdateErr::PermanentFailure => {
450+
let (channel_id, mut chan) = $entry.remove_entry();
451+
if let Some(short_id) = chan.get_short_channel_id() {
452+
$channel_state.short_to_id.remove(&short_id);
453+
}
454+
break Err(MsgHandleErrInternal::from_finish_shutdown("ChannelMonitor storage failure", channel_id, chan.force_shutdown(), $self.get_channel_update(&chan).ok()))
455+
},
456+
ChannelMonitorUpdateErr::TemporaryFailure => {
457+
$entry.get_mut().monitor_update_failed($action_type);
458+
},
459+
}
460+
}
461+
}
462+
445463
impl ChannelManager {
446464
/// Constructs a new ChannelManager to hold several channels and route between them.
447465
///
@@ -667,33 +685,6 @@ impl ChannelManager {
667685
}
668686
}
669687

670-
fn handle_monitor_update_fail(&self, mut channel_state_lock: MutexGuard<ChannelHolder>, channel_id: &[u8; 32], err: ChannelMonitorUpdateErr, reason: RAACommitmentOrder) {
671-
match err {
672-
ChannelMonitorUpdateErr::PermanentFailure => {
673-
let mut chan = {
674-
let channel_state = channel_state_lock.borrow_parts();
675-
let chan = channel_state.by_id.remove(channel_id).expect("monitor_update_failed must be called within the same lock as the channel get!");
676-
if let Some(short_id) = chan.get_short_channel_id() {
677-
channel_state.short_to_id.remove(&short_id);
678-
}
679-
chan
680-
};
681-
mem::drop(channel_state_lock);
682-
self.finish_force_close_channel(chan.force_shutdown());
683-
if let Ok(update) = self.get_channel_update(&chan) {
684-
let mut channel_state = self.channel_state.lock().unwrap();
685-
channel_state.pending_msg_events.push(events::MessageSendEvent::BroadcastChannelUpdate {
686-
msg: update
687-
});
688-
}
689-
},
690-
ChannelMonitorUpdateErr::TemporaryFailure => {
691-
let channel = channel_state_lock.by_id.get_mut(channel_id).expect("monitor_update_failed must be called within the same lock as the channel get!");
692-
channel.monitor_update_failed(reason);
693-
},
694-
}
695-
}
696-
697688
#[inline]
698689
fn gen_rho_mu_from_shared_secret(shared_secret: &[u8]) -> ([u8; 32], [u8; 32]) {
699690
assert_eq!(shared_secret.len(), 32);
@@ -1193,7 +1184,17 @@ impl ChannelManager {
11931184
/// May generate a SendHTLCs message event on success, which should be relayed.
11941185
///
11951186
/// Raises APIError::RoutError when invalid route or forward parameter
1196-
/// (cltv_delta, fee, node public key) is specified
1187+
/// (cltv_delta, fee, node public key) is specified.
1188+
/// Raises APIError::ChannelUnavailable if the next-hop channel is not available for updates
1189+
/// (including due to previous monitor update failure or new permanent monitor update failure).
1190+
/// Raised APIError::MonitorUpdateFailed if a new monitor update failure prevented sending the
1191+
/// relevant updates.
1192+
///
1193+
/// In case of APIError::RouteError/APIError::ChannelUnavailable, the payment send has failed
1194+
/// and you may wish to retry via a different route immediately.
1195+
/// In case of APIError::MonitorUpdateFailed, the commitment update has been irrevocably
1196+
/// committed on our end and we're just waiting for a monitor update to send it. Do NOT retry
1197+
/// the payment via a different route unless you intend to pay twice!
11971198
pub fn send_payment(&self, route: Route, payment_hash: [u8; 32]) -> Result<(), APIError> {
11981199
if route.hops.len() < 1 || route.hops.len() > 20 {
11991200
return Err(APIError::RouteError{err: "Route didn't go anywhere/had bogus size"});
@@ -1224,45 +1225,46 @@ impl ChannelManager {
12241225
Some(id) => id.clone(),
12251226
};
12261227

1227-
match {
1228-
let channel_state = channel_lock.borrow_parts();
1229-
if let hash_map::Entry::Occupied(mut chan) = channel_state.by_id.entry(id) {
1228+
let channel_state = channel_lock.borrow_parts();
1229+
if let hash_map::Entry::Occupied(mut chan) = channel_state.by_id.entry(id) {
1230+
match {
12301231
if chan.get().get_their_node_id() != route.hops.first().unwrap().pubkey {
12311232
return Err(APIError::RouteError{err: "Node ID mismatch on first hop!"});
12321233
}
1233-
if chan.get().is_awaiting_monitor_update() {
1234-
return Err(APIError::MonitorUpdateFailed);
1235-
}
12361234
if !chan.get().is_live() {
1237-
return Err(APIError::ChannelUnavailable{err: "Peer for first hop currently disconnected!"});
1235+
return Err(APIError::ChannelUnavailable{err: "Peer for first hop currently disconnected/pending monitor update!"});
12381236
}
12391237
break_chan_entry!(self, chan.get_mut().send_htlc_and_commit(htlc_msat, payment_hash.clone(), htlc_cltv, HTLCSource::OutboundRoute {
12401238
route: route.clone(),
12411239
session_priv: session_priv.clone(),
12421240
first_hop_htlc_msat: htlc_msat,
12431241
}, onion_packet), channel_state, chan)
1244-
} else { unreachable!(); }
1245-
} {
1246-
Some((update_add, commitment_signed, chan_monitor)) => {
1247-
if let Err(e) = self.monitor.add_update_monitor(chan_monitor.get_funding_txo().unwrap(), chan_monitor) {
1248-
self.handle_monitor_update_fail(channel_lock, &id, e, RAACommitmentOrder::CommitmentFirst);
1249-
return Err(APIError::MonitorUpdateFailed);
1250-
}
1242+
} {
1243+
Some((update_add, commitment_signed, chan_monitor)) => {
1244+
if let Err(e) = self.monitor.add_update_monitor(chan_monitor.get_funding_txo().unwrap(), chan_monitor) {
1245+
maybe_break_monitor_err!(self, e, channel_state, chan, RAACommitmentOrder::CommitmentFirst);
1246+
// Note that MonitorUpdateFailed here indicates (per function docs)
1247+
// that we will resent the commitment update once we unfree monitor
1248+
// updating, so we have to take special care that we don't return
1249+
// something else in case we will resend later!
1250+
return Err(APIError::MonitorUpdateFailed);
1251+
}
12511252

1252-
channel_lock.pending_msg_events.push(events::MessageSendEvent::UpdateHTLCs {
1253-
node_id: route.hops.first().unwrap().pubkey,
1254-
updates: msgs::CommitmentUpdate {
1255-
update_add_htlcs: vec![update_add],
1256-
update_fulfill_htlcs: Vec::new(),
1257-
update_fail_htlcs: Vec::new(),
1258-
update_fail_malformed_htlcs: Vec::new(),
1259-
update_fee: None,
1260-
commitment_signed,
1261-
},
1262-
});
1263-
},
1264-
None => {},
1265-
}
1253+
channel_state.pending_msg_events.push(events::MessageSendEvent::UpdateHTLCs {
1254+
node_id: route.hops.first().unwrap().pubkey,
1255+
updates: msgs::CommitmentUpdate {
1256+
update_add_htlcs: vec![update_add],
1257+
update_fulfill_htlcs: Vec::new(),
1258+
update_fail_htlcs: Vec::new(),
1259+
update_fail_malformed_htlcs: Vec::new(),
1260+
update_fee: None,
1261+
commitment_signed,
1262+
},
1263+
});
1264+
},
1265+
None => {},
1266+
}
1267+
} else { unreachable!(); }
12661268
return Ok(());
12671269
};
12681270

@@ -1441,7 +1443,7 @@ impl ChannelManager {
14411443
},
14421444
};
14431445
if let Err(_e) = self.monitor.add_update_monitor(monitor.get_funding_txo().unwrap(), monitor) {
1444-
unimplemented!();// but def dont push the event...
1446+
unimplemented!();
14451447
}
14461448
channel_state.pending_msg_events.push(events::MessageSendEvent::UpdateHTLCs {
14471449
node_id: forward_chan.get_their_node_id(),
@@ -6946,15 +6948,19 @@ mod tests {
69466948
let (_, payment_hash_1) = get_payment_preimage_hash!(nodes[0]);
69476949

69486950
*nodes[0].chan_monitor.update_ret.lock().unwrap() = Err(ChannelMonitorUpdateErr::PermanentFailure);
6949-
if let Err(APIError::MonitorUpdateFailed) = nodes[0].node.send_payment(route, payment_hash_1) {} else { panic!(); }
6951+
if let Err(APIError::ChannelUnavailable {..}) = nodes[0].node.send_payment(route, payment_hash_1) {} else { panic!(); }
69506952
check_added_monitors!(nodes[0], 1);
69516953

69526954
let events_1 = nodes[0].node.get_and_clear_pending_msg_events();
6953-
assert_eq!(events_1.len(), 1);
6955+
assert_eq!(events_1.len(), 2);
69546956
match events_1[0] {
69556957
MessageSendEvent::BroadcastChannelUpdate { .. } => {},
69566958
_ => panic!("Unexpected event"),
69576959
};
6960+
match events_1[1] {
6961+
MessageSendEvent::HandleError { node_id, .. } => assert_eq!(node_id, nodes[1].node.get_our_node_id()),
6962+
_ => panic!("Unexpected event"),
6963+
};
69586964

69596965
// TODO: Once we hit the chain with the failure transaction we should check that we get a
69606966
// PaymentFailed event

0 commit comments

Comments
 (0)