Skip to content

Commit 1a33f99

Browse files
committed
Use the new monitor persistence flow for funding_created handling
Building on the previous commits, this finishes our transition to doing all message-sending in the monitor update completion pipeline, unifying our immediate- and async- `ChannelMonitor` update and persistence flows.
1 parent b75f810 commit 1a33f99

File tree

3 files changed

+46
-53
lines changed

3 files changed

+46
-53
lines changed

lightning/src/ln/channel.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2268,9 +2268,9 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
22682268

22692269
pub fn funding_created<SP: Deref, L: Deref>(
22702270
&mut self, msg: &msgs::FundingCreated, best_block: BestBlock, signer_provider: &SP, logger: &L
2271-
) -> Result<(msgs::FundingSigned, ChannelMonitor<<SP::Target as SignerProvider>::Signer>, Option<msgs::ChannelReady>), ChannelError>
2271+
) -> Result<(msgs::FundingSigned, ChannelMonitor<Signer>), ChannelError>
22722272
where
2273-
SP::Target: SignerProvider,
2273+
SP::Target: SignerProvider<Signer=Signer>,
22742274
L::Target: Logger
22752275
{
22762276
if self.is_outbound() {
@@ -2346,10 +2346,13 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
23462346

23472347
log_info!(logger, "Generated funding_signed for peer for channel {}", log_bytes!(self.channel_id()));
23482348

2349+
let need_channel_ready = self.check_get_channel_ready(0).is_some();
2350+
self.monitor_updating_paused(false, false, need_channel_ready, Vec::new(), Vec::new(), Vec::new());
2351+
23492352
Ok((msgs::FundingSigned {
23502353
channel_id: self.channel_id,
23512354
signature
2352-
}, channel_monitor, self.check_get_channel_ready(0)))
2355+
}, channel_monitor))
23532356
}
23542357

23552358
/// Handles a funding_signed message from the remote end.
@@ -3740,15 +3743,16 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
37403743
}
37413744

37423745
/// Indicates that a ChannelMonitor update is in progress and has not yet been fully persisted.
3743-
/// This must be called immediately after the [`chain::Watch`] call which returned
3744-
/// [`ChannelMonitorUpdateStatus::InProgress`].
3746+
/// This must be called before we return the [`ChannelMonitorUpdate`] back to the
3747+
/// [`ChannelManager`], which will call [`Self::monitor_updating_restored`] once the monitor
3748+
/// update completes (potentially immediately).
37453749
/// The messages which were generated with the monitor update must *not* have been sent to the
37463750
/// remote end, and must instead have been dropped. They will be regenerated when
37473751
/// [`Self::monitor_updating_restored`] is called.
37483752
///
37493753
/// [`chain::Watch`]: crate::chain::Watch
37503754
/// [`ChannelMonitorUpdateStatus::InProgress`]: crate::chain::ChannelMonitorUpdateStatus::InProgress
3751-
pub fn monitor_updating_paused(&mut self, resend_raa: bool, resend_commitment: bool,
3755+
fn monitor_updating_paused(&mut self, resend_raa: bool, resend_commitment: bool,
37523756
resend_channel_ready: bool, mut pending_forwards: Vec<(PendingHTLCInfo, u64)>,
37533757
mut pending_fails: Vec<(HTLCSource, PaymentHash, HTLCFailReason)>,
37543758
mut pending_finalized_claimed_htlcs: Vec<HTLCSource>
@@ -7189,7 +7193,7 @@ mod tests {
71897193
}]};
71907194
let funding_outpoint = OutPoint{ txid: tx.txid(), index: 0 };
71917195
let funding_created_msg = node_a_chan.get_outbound_funding_created(tx.clone(), funding_outpoint, &&logger).unwrap();
7192-
let (funding_signed_msg, _, _) = node_b_chan.funding_created(&funding_created_msg, best_block, &&keys_provider, &&logger).unwrap();
7196+
let (funding_signed_msg, _) = node_b_chan.funding_created(&funding_created_msg, best_block, &&keys_provider, &&logger).unwrap();
71937197

71947198
// Node B --> Node A: funding signed
71957199
let _ = node_a_chan.funding_signed(&funding_signed_msg, best_block, &&keys_provider, &&logger);

lightning/src/ln/channelmanager.rs

Lines changed: 32 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -4414,60 +4414,31 @@ where
44144414
}
44154415

44164416
fn internal_funding_created(&self, counterparty_node_id: &PublicKey, msg: &msgs::FundingCreated) -> Result<(), MsgHandleErrInternal> {
4417+
let best_block = *self.best_block.read().unwrap();
4418+
44174419
let per_peer_state = self.per_peer_state.read().unwrap();
44184420
let peer_state_mutex = per_peer_state.get(counterparty_node_id)
44194421
.ok_or_else(|| {
44204422
debug_assert!(false);
44214423
MsgHandleErrInternal::send_err_msg_no_close(format!("Can't find a peer matching the passed counterparty node_id {}", counterparty_node_id), msg.temporary_channel_id)
44224424
})?;
4423-
let ((funding_msg, monitor, mut channel_ready), mut chan) = {
4424-
let best_block = *self.best_block.read().unwrap();
4425-
let mut peer_state_lock = peer_state_mutex.lock().unwrap();
4426-
let peer_state = &mut *peer_state_lock;
4425+
4426+
let mut peer_state_lock = peer_state_mutex.lock().unwrap();
4427+
let peer_state = &mut *peer_state_lock;
4428+
let ((funding_msg, monitor), chan) =
44274429
match peer_state.channel_by_id.entry(msg.temporary_channel_id) {
44284430
hash_map::Entry::Occupied(mut chan) => {
44294431
(try_chan_entry!(self, chan.get_mut().funding_created(msg, best_block, &self.signer_provider, &self.logger), chan), chan.remove())
44304432
},
44314433
hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close(format!("Got a message for a channel from the wrong node! No such channel for the passed counterparty_node_id {}", counterparty_node_id), msg.temporary_channel_id))
4432-
}
4433-
};
4434-
// Because we have exclusive ownership of the channel here we can release the peer_state
4435-
// lock before watch_channel
4436-
match self.chain_monitor.watch_channel(monitor.get_funding_txo().0, monitor) {
4437-
ChannelMonitorUpdateStatus::Completed => {},
4438-
ChannelMonitorUpdateStatus::PermanentFailure => {
4439-
// Note that we reply with the new channel_id in error messages if we gave up on the
4440-
// channel, not the temporary_channel_id. This is compatible with ourselves, but the
4441-
// spec is somewhat ambiguous here. Not a huge deal since we'll send error messages for
4442-
// any messages referencing a previously-closed channel anyway.
4443-
// We do not propagate the monitor update to the user as it would be for a monitor
4444-
// that we didn't manage to store (and that we don't care about - we don't respond
4445-
// with the funding_signed so the channel can never go on chain).
4446-
let (_monitor_update, failed_htlcs) = chan.force_shutdown(false);
4447-
assert!(failed_htlcs.is_empty());
4448-
return Err(MsgHandleErrInternal::send_err_msg_no_close("ChannelMonitor storage failure".to_owned(), funding_msg.channel_id));
4449-
},
4450-
ChannelMonitorUpdateStatus::InProgress => {
4451-
// There's no problem signing a counterparty's funding transaction if our monitor
4452-
// hasn't persisted to disk yet - we can't lose money on a transaction that we haven't
4453-
// accepted payment from yet. We do, however, need to wait to send our channel_ready
4454-
// until we have persisted our monitor.
4455-
chan.monitor_updating_paused(false, false, channel_ready.is_some(), Vec::new(), Vec::new(), Vec::new());
4456-
channel_ready = None; // Don't send the channel_ready now
4457-
},
4458-
}
4459-
// It's safe to unwrap as we've held the `per_peer_state` read lock since checking that the
4460-
// peer exists, despite the inner PeerState potentially having no channels after removing
4461-
// the channel above.
4462-
let mut peer_state_lock = peer_state_mutex.lock().unwrap();
4463-
let peer_state = &mut *peer_state_lock;
4434+
};
4435+
44644436
match peer_state.channel_by_id.entry(funding_msg.channel_id) {
44654437
hash_map::Entry::Occupied(_) => {
4466-
return Err(MsgHandleErrInternal::send_err_msg_no_close("Already had channel with the new channel_id".to_owned(), funding_msg.channel_id))
4438+
Err(MsgHandleErrInternal::send_err_msg_no_close("Already had channel with the new channel_id".to_owned(), funding_msg.channel_id))
44674439
},
44684440
hash_map::Entry::Vacant(e) => {
4469-
let mut id_to_peer = self.id_to_peer.lock().unwrap();
4470-
match id_to_peer.entry(chan.channel_id()) {
4441+
match self.id_to_peer.lock().unwrap().entry(chan.channel_id()) {
44714442
hash_map::Entry::Occupied(_) => {
44724443
return Err(MsgHandleErrInternal::send_err_msg_no_close(
44734444
"The funding_created message had the same funding_txid as an existing channel - funding is not possible".to_owned(),
@@ -4477,17 +4448,35 @@ where
44774448
i_e.insert(chan.get_counterparty_node_id());
44784449
}
44794450
}
4451+
4452+
// There's no problem signing a counterparty's funding transaction if our monitor
4453+
// hasn't persisted to disk yet - we can't lose money on a transaction that we haven't
4454+
// accepted payment from yet. We do, however, need to wait to send our channel_ready
4455+
// until we have persisted our monitor.
4456+
let new_channel_id = funding_msg.channel_id;
44804457
peer_state.pending_msg_events.push(events::MessageSendEvent::SendFundingSigned {
44814458
node_id: counterparty_node_id.clone(),
44824459
msg: funding_msg,
44834460
});
4484-
if let Some(msg) = channel_ready {
4485-
send_channel_ready!(self, peer_state.pending_msg_events, chan, msg);
4461+
4462+
let monitor_res = self.chain_monitor.watch_channel(monitor.get_funding_txo().0, monitor);
4463+
4464+
let chan = e.insert(chan);
4465+
let mut res = handle_new_monitor_update!(self, monitor_res, 0, peer_state_lock, peer_state, chan, MANUALLY_REMOVING, { peer_state.channel_by_id.remove(&new_channel_id) });
4466+
4467+
// Note that we reply with the new channel_id in error messages if we gave up on the
4468+
// channel, not the temporary_channel_id. This is compatible with ourselves, but the
4469+
// spec is somewhat ambiguous here. Not a huge deal since we'll send error messages for
4470+
// any messages referencing a previously-closed channel anyway.
4471+
// We do not propagate the monitor update to the user as it would be for a monitor
4472+
// that we didn't manage to store (and that we don't care about - we don't respond
4473+
// with the funding_signed so the channel can never go on chain).
4474+
if let Err(MsgHandleErrInternal { shutdown_finish: Some((res, _)), .. }) = &mut res {
4475+
res.0 = None;
44864476
}
4487-
e.insert(chan);
4477+
res
44884478
}
44894479
}
4490-
Ok(())
44914480
}
44924481

44934482
fn internal_funding_signed(&self, counterparty_node_id: &PublicKey, msg: &msgs::FundingSigned) -> Result<(), MsgHandleErrInternal> {

lightning/src/ln/functional_tests.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8693,9 +8693,9 @@ fn test_duplicate_chan_id() {
86938693
};
86948694
check_added_monitors!(nodes[0], 0);
86958695
nodes[1].node.handle_funding_created(&nodes[0].node.get_our_node_id(), &funding_created);
8696-
// At this point we'll try to add a duplicate channel monitor, which will be rejected, but
8697-
// still needs to be cleared here.
8698-
check_added_monitors!(nodes[1], 1);
8696+
// At this point we'll look up if the channel_id is present and immediately fail the channel
8697+
// without trying to persist the `ChannelMonitor.
8698+
check_added_monitors!(nodes[1], 0);
86998699

87008700
// ...still, nodes[1] will reject the duplicate channel.
87018701
{

0 commit comments

Comments
 (0)