Skip to content

Commit 8fc8534

Browse files
committed
Lean on the holding cell for commitments when updating fees
Like the previous commit, here we update the update_fee+commit logic to simply push the fee update into the holding cell and then use the standard holding-cell-freeing codepaths to actually send the commitment update. This removes a substantial amount of code, reducing redundant codepaths and keeping channel state machine logic in channel.rs.
1 parent 668a798 commit 8fc8534

File tree

2 files changed

+34
-113
lines changed

2 files changed

+34
-113
lines changed

lightning/src/ln/channel.rs

Lines changed: 22 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -3251,7 +3251,7 @@ impl<Signer: Sign> Channel<Signer> {
32513251
return Ok((None, htlcs_to_fail));
32523252
}
32533253
let update_fee = if let Some(feerate) = self.holding_cell_update_fee.take() {
3254-
self.send_update_fee(feerate, logger)
3254+
self.send_update_fee(feerate, false, logger)
32553255
} else {
32563256
None
32573257
};
@@ -3551,12 +3551,22 @@ impl<Signer: Sign> Channel<Signer> {
35513551
}
35523552
}
35533553

3554+
/// Queues up an outbound update fee by placing it in the holding cell. You should call
3555+
/// `maybe_free_holding_cell_htlcs` in order to actually generate and send the commitment
3556+
/// update.
3557+
pub fn queue_update_fee<L: Deref>(&mut self, feerate_per_kw: u32, logger: &L) where L::Target: Logger {
3558+
let msg_opt = self.send_update_fee(feerate_per_kw, true, logger);
3559+
assert!(msg_opt.is_none(), "We forced holding cell?");
3560+
}
3561+
35543562
/// Adds a pending update to this channel. See the doc for send_htlc for
35553563
/// further details on the optionness of the return value.
35563564
/// If our balance is too low to cover the cost of the next commitment transaction at the
35573565
/// new feerate, the update is cancelled.
3558-
/// You MUST call send_commitment prior to any other calls on this Channel
3559-
fn send_update_fee<L: Deref>(&mut self, feerate_per_kw: u32, logger: &L) -> Option<msgs::UpdateFee> where L::Target: Logger {
3566+
///
3567+
/// You MUST call `send_commitment_no_state_update` prior to any other calls on this Channel if
3568+
/// `force_holding_cell` is false.
3569+
fn send_update_fee<L: Deref>(&mut self, feerate_per_kw: u32, mut force_holding_cell: bool, logger: &L) -> Option<msgs::UpdateFee> where L::Target: Logger {
35603570
if !self.is_outbound() {
35613571
panic!("Cannot send fee from inbound channel");
35623572
}
@@ -3593,6 +3603,10 @@ impl<Signer: Sign> Channel<Signer> {
35933603
}
35943604

35953605
if (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32 | ChannelState::MonitorUpdateInProgress as u32)) != 0 {
3606+
force_holding_cell = true;
3607+
}
3608+
3609+
if force_holding_cell {
35963610
self.holding_cell_update_fee = Some(feerate_per_kw);
35973611
return None;
35983612
}
@@ -3606,16 +3620,6 @@ impl<Signer: Sign> Channel<Signer> {
36063620
})
36073621
}
36083622

3609-
pub fn send_update_fee_and_commit<L: Deref>(&mut self, feerate_per_kw: u32, logger: &L) -> Result<Option<(msgs::UpdateFee, msgs::CommitmentSigned, ChannelMonitorUpdate)>, ChannelError> where L::Target: Logger {
3610-
match self.send_update_fee(feerate_per_kw, logger) {
3611-
Some(update_fee) => {
3612-
let (commitment_signed, monitor_update) = self.send_commitment_no_status_check(logger)?;
3613-
Ok(Some((update_fee, commitment_signed, monitor_update)))
3614-
},
3615-
None => Ok(None)
3616-
}
3617-
}
3618-
36193623
/// Removes any uncommitted inbound HTLCs and resets the state of uncommitted outbound HTLC
36203624
/// updates, to be used on peer disconnection. After this, update_*_htlc messages need to be
36213625
/// resent.
@@ -5514,8 +5518,8 @@ impl<Signer: Sign> Channel<Signer> {
55145518
/// we may not yet have sent the previous commitment update messages and will need to
55155519
/// regenerate them.
55165520
///
5517-
/// You MUST call send_commitment prior to calling any other methods on this Channel if
5518-
/// `force_holding_cell` is false.
5521+
/// You MUST call `send_commitment_no_state_update` prior to calling any other methods on this
5522+
/// Channel if `force_holding_cell` is false.
55195523
///
55205524
/// If an Err is returned, it's a ChannelError::Ignore!
55215525
fn send_htlc<L: Deref>(&mut self, amount_msat: u64, payment_hash: PaymentHash, cltv_expiry: u32, source: HTLCSource,
@@ -5653,41 +5657,6 @@ impl<Signer: Sign> Channel<Signer> {
56535657
Ok(Some(res))
56545658
}
56555659

5656-
/// Creates a signed commitment transaction to send to the remote peer.
5657-
/// Always returns a ChannelError::Close if an immediately-preceding (read: the
5658-
/// last call to this Channel) send_htlc returned Ok(Some(_)) and there is an Err.
5659-
/// May panic if called except immediately after a successful, Ok(Some(_))-returning send_htlc.
5660-
pub fn send_commitment<L: Deref>(&mut self, logger: &L) -> Result<(msgs::CommitmentSigned, ChannelMonitorUpdate), ChannelError> where L::Target: Logger {
5661-
if (self.channel_state & (ChannelState::ChannelReady as u32)) != (ChannelState::ChannelReady as u32) {
5662-
panic!("Cannot create commitment tx until channel is fully established");
5663-
}
5664-
if (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32)) == (ChannelState::AwaitingRemoteRevoke as u32) {
5665-
panic!("Cannot create commitment tx until remote revokes their previous commitment");
5666-
}
5667-
if (self.channel_state & (ChannelState::PeerDisconnected as u32)) == (ChannelState::PeerDisconnected as u32) {
5668-
panic!("Cannot create commitment tx while disconnected, as send_htlc will have returned an Err so a send_commitment precondition has been violated");
5669-
}
5670-
if (self.channel_state & (ChannelState::MonitorUpdateInProgress as u32)) == (ChannelState::MonitorUpdateInProgress as u32) {
5671-
panic!("Cannot create commitment tx while awaiting monitor update unfreeze, as send_htlc will have returned an Err so a send_commitment precondition has been violated");
5672-
}
5673-
let mut have_updates = self.is_outbound() && self.pending_update_fee.is_some();
5674-
for htlc in self.pending_outbound_htlcs.iter() {
5675-
if let OutboundHTLCState::LocalAnnounced(_) = htlc.state {
5676-
have_updates = true;
5677-
}
5678-
if have_updates { break; }
5679-
}
5680-
for htlc in self.pending_inbound_htlcs.iter() {
5681-
if let InboundHTLCState::LocalRemoved(_) = htlc.state {
5682-
have_updates = true;
5683-
}
5684-
if have_updates { break; }
5685-
}
5686-
if !have_updates {
5687-
panic!("Cannot create commitment tx until we have some updates to send");
5688-
}
5689-
self.send_commitment_no_status_check(logger)
5690-
}
56915660
/// Only fails in case of bad keys
56925661
fn send_commitment_no_status_check<L: Deref>(&mut self, logger: &L) -> Result<(msgs::CommitmentSigned, ChannelMonitorUpdate), ChannelError> where L::Target: Logger {
56935662
log_trace!(logger, "Updating HTLC state for a newly-sent commitment_signed...");
@@ -5810,8 +5779,9 @@ impl<Signer: Sign> Channel<Signer> {
58105779

58115780
/// Adds a pending outbound HTLC to this channel, and creates a signed commitment transaction
58125781
/// to send to the remote peer in one go.
5813-
/// Shorthand for calling send_htlc() followed by send_commitment(), see docs on those for
5814-
/// more info.
5782+
///
5783+
/// Shorthand for calling send_htlc() followed by a commitment update, see docs on `send_htlc`
5784+
/// and `send_commitment_no_state_update` for more info.
58155785
pub fn send_htlc_and_commit<L: Deref>(&mut self, amount_msat: u64, payment_hash: PaymentHash, cltv_expiry: u32, source: HTLCSource, onion_routing_packet: msgs::OnionPacket, logger: &L) -> Result<Option<(msgs::UpdateAddHTLC, msgs::CommitmentSigned, ChannelMonitorUpdate)>, ChannelError> where L::Target: Logger {
58165786
match self.send_htlc(amount_msat, payment_hash, cltv_expiry, source, onion_routing_packet, false, logger)? {
58175787
Some(update_add_htlc) => {

lightning/src/ln/channelmanager.rs

Lines changed: 12 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -3586,59 +3586,24 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
35863586
self.process_background_events();
35873587
}
35883588

3589-
fn update_channel_fee(&self, pending_msg_events: &mut Vec<events::MessageSendEvent>, chan_id: &[u8; 32], chan: &mut Channel<<K::Target as KeysInterface>::Signer>, new_feerate: u32) -> (bool, NotifyOption, Result<(), MsgHandleErrInternal>) {
3590-
if !chan.is_outbound() { return (true, NotifyOption::SkipPersist, Ok(())); }
3589+
fn update_channel_fee(&self, chan_id: &[u8; 32], chan: &mut Channel<<K::Target as KeysInterface>::Signer>, new_feerate: u32) -> NotifyOption {
3590+
if !chan.is_outbound() { return NotifyOption::SkipPersist; }
35913591
// If the feerate has decreased by less than half, don't bother
35923592
if new_feerate <= chan.get_feerate() && new_feerate * 2 > chan.get_feerate() {
35933593
log_trace!(self.logger, "Channel {} does not qualify for a feerate change from {} to {}.",
35943594
log_bytes!(chan_id[..]), chan.get_feerate(), new_feerate);
3595-
return (true, NotifyOption::SkipPersist, Ok(()));
3595+
return NotifyOption::SkipPersist;
35963596
}
35973597
if !chan.is_live() {
35983598
log_trace!(self.logger, "Channel {} does not qualify for a feerate change from {} to {} as it cannot currently be updated (probably the peer is disconnected).",
35993599
log_bytes!(chan_id[..]), chan.get_feerate(), new_feerate);
3600-
return (true, NotifyOption::SkipPersist, Ok(()));
3600+
return NotifyOption::SkipPersist;
36013601
}
36023602
log_trace!(self.logger, "Channel {} qualifies for a feerate change from {} to {}.",
36033603
log_bytes!(chan_id[..]), chan.get_feerate(), new_feerate);
36043604

3605-
let mut retain_channel = true;
3606-
let res = match chan.send_update_fee_and_commit(new_feerate, &self.logger) {
3607-
Ok(res) => Ok(res),
3608-
Err(e) => {
3609-
let (drop, res) = convert_chan_err!(self, e, chan, chan_id);
3610-
if drop { retain_channel = false; }
3611-
Err(res)
3612-
}
3613-
};
3614-
let ret_err = match res {
3615-
Ok(Some((update_fee, commitment_signed, monitor_update))) => {
3616-
match self.chain_monitor.update_channel(chan.get_funding_txo().unwrap(), monitor_update) {
3617-
ChannelMonitorUpdateStatus::Completed => {
3618-
pending_msg_events.push(events::MessageSendEvent::UpdateHTLCs {
3619-
node_id: chan.get_counterparty_node_id(),
3620-
updates: msgs::CommitmentUpdate {
3621-
update_add_htlcs: Vec::new(),
3622-
update_fulfill_htlcs: Vec::new(),
3623-
update_fail_htlcs: Vec::new(),
3624-
update_fail_malformed_htlcs: Vec::new(),
3625-
update_fee: Some(update_fee),
3626-
commitment_signed,
3627-
},
3628-
});
3629-
Ok(())
3630-
},
3631-
e => {
3632-
let (res, drop) = handle_monitor_update_res!(self, e, chan, RAACommitmentOrder::CommitmentFirst, chan_id, COMMITMENT_UPDATE_ONLY);
3633-
if drop { retain_channel = false; }
3634-
res
3635-
}
3636-
}
3637-
},
3638-
Ok(None) => Ok(()),
3639-
Err(e) => Err(e),
3640-
};
3641-
(retain_channel, NotifyOption::DoPersist, ret_err)
3605+
chan.queue_update_fee(new_feerate, &self.logger);
3606+
NotifyOption::DoPersist
36423607
}
36433608

36443609
#[cfg(fuzzing)]
@@ -3652,19 +3617,10 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
36523617

36533618
let new_feerate = self.fee_estimator.bounded_sat_per_1000_weight(ConfirmationTarget::Normal);
36543619

3655-
let mut handle_errors = Vec::new();
3656-
{
3657-
let mut channel_state_lock = self.channel_state.lock().unwrap();
3658-
let channel_state = &mut *channel_state_lock;
3659-
let pending_msg_events = &mut channel_state.pending_msg_events;
3660-
channel_state.by_id.retain(|chan_id, chan| {
3661-
let (retain_channel, chan_needs_persist, err) = self.update_channel_fee(pending_msg_events, chan_id, chan, new_feerate);
3662-
if chan_needs_persist == NotifyOption::DoPersist { should_persist = NotifyOption::DoPersist; }
3663-
if err.is_err() {
3664-
handle_errors.push(err);
3665-
}
3666-
retain_channel
3667-
});
3620+
let mut channel_state = self.channel_state.lock().unwrap();
3621+
for (chan_id, chan) in channel_state.by_id.iter_mut() {
3622+
let chan_needs_persist = self.update_channel_fee(chan_id, chan, new_feerate);
3623+
if chan_needs_persist == NotifyOption::DoPersist { should_persist = NotifyOption::DoPersist; }
36683624
}
36693625

36703626
should_persist
@@ -3729,20 +3685,15 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
37293685

37303686
let new_feerate = self.fee_estimator.bounded_sat_per_1000_weight(ConfirmationTarget::Normal);
37313687

3732-
let mut handle_errors = Vec::new();
3688+
let mut handle_errors: Vec<(Result<(), _>, _)> = Vec::new();
37333689
let mut timed_out_mpp_htlcs = Vec::new();
37343690
{
37353691
let mut channel_state_lock = self.channel_state.lock().unwrap();
37363692
let channel_state = &mut *channel_state_lock;
37373693
let pending_msg_events = &mut channel_state.pending_msg_events;
37383694
channel_state.by_id.retain(|chan_id, chan| {
3739-
let counterparty_node_id = chan.get_counterparty_node_id();
3740-
let (retain_channel, chan_needs_persist, err) = self.update_channel_fee(pending_msg_events, chan_id, chan, new_feerate);
3695+
let chan_needs_persist = self.update_channel_fee(chan_id, chan, new_feerate);
37413696
if chan_needs_persist == NotifyOption::DoPersist { should_persist = NotifyOption::DoPersist; }
3742-
if err.is_err() {
3743-
handle_errors.push((err, counterparty_node_id));
3744-
}
3745-
if !retain_channel { return false; }
37463697

37473698
if let Err(e) = chan.timer_check_closing_negotiation_progress() {
37483699
let (needs_close, err) = convert_chan_err!(self, e, chan, chan_id);

0 commit comments

Comments
 (0)