Skip to content

Commit 4e4f128

Browse files
authored
Merge pull request #3894 from wpaulino/renegotiated-funding-locked-monitor-update
Introduce RenegotiatedFundingLocked monitor update variant
2 parents 1378ae2 + 22d5428 commit 4e4f128

File tree

4 files changed

+268
-135
lines changed

4 files changed

+268
-135
lines changed

lightning/src/chain/channelmonitor.rs

Lines changed: 55 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -678,6 +678,9 @@ pub(crate) enum ChannelMonitorUpdateStep {
678678
holder_commitment_tx: HolderCommitmentTransaction,
679679
counterparty_commitment_tx: CommitmentTransaction,
680680
},
681+
RenegotiatedFundingLocked {
682+
funding_txid: Txid,
683+
},
681684
}
682685

683686
impl ChannelMonitorUpdateStep {
@@ -693,6 +696,7 @@ impl ChannelMonitorUpdateStep {
693696
ChannelMonitorUpdateStep::ChannelForceClosed { .. } => "ChannelForceClosed",
694697
ChannelMonitorUpdateStep::ShutdownScript { .. } => "ShutdownScript",
695698
ChannelMonitorUpdateStep::RenegotiatedFunding { .. } => "RenegotiatedFunding",
699+
ChannelMonitorUpdateStep::RenegotiatedFundingLocked { .. } => "RenegotiatedFundingLocked",
696700
}
697701
}
698702
}
@@ -741,6 +745,9 @@ impl_writeable_tlv_based_enum_upgradable!(ChannelMonitorUpdateStep,
741745
(3, holder_commitment_tx, required),
742746
(5, counterparty_commitment_tx, required),
743747
},
748+
(12, RenegotiatedFundingLocked) => {
749+
(1, funding_txid, required),
750+
},
744751
);
745752

746753
/// Indicates whether the balance is derived from a cooperative close, a force-close
@@ -1088,6 +1095,10 @@ impl FundingScope {
10881095
fn funding_txid(&self) -> Txid {
10891096
self.funding_outpoint().txid
10901097
}
1098+
1099+
fn is_splice(&self) -> bool {
1100+
self.channel_parameters.splice_parent_funding_txid.is_some()
1101+
}
10911102
}
10921103

10931104
impl_writeable_tlv_based!(FundingScope, {
@@ -1115,7 +1126,7 @@ pub(crate) struct ChannelMonitorImpl<Signer: EcdsaChannelSigner> {
11151126
channel_keys_id: [u8; 32],
11161127
holder_revocation_basepoint: RevocationBasepoint,
11171128
channel_id: ChannelId,
1118-
first_confirmed_funding_txo: OutPoint,
1129+
first_negotiated_funding_txo: OutPoint,
11191130

11201131
counterparty_commitment_params: CounterpartyCommitmentParameters,
11211132

@@ -1183,8 +1194,6 @@ pub(crate) struct ChannelMonitorImpl<Signer: EcdsaChannelSigner> {
11831194
// interface knows about the TXOs that we want to be notified of spends of. We could probably
11841195
// be smart and derive them from the above storage fields, but its much simpler and more
11851196
// Obviously Correct (tm) if we just keep track of them explicitly.
1186-
//
1187-
// TODO: Remove entries for stale funding transactions on `splice_locked`.
11881197
outputs_to_watch: HashMap<Txid, Vec<(u32, ScriptBuf)>>,
11891198

11901199
#[cfg(any(test, feature = "_test_utils"))]
@@ -1542,7 +1551,7 @@ impl<Signer: EcdsaChannelSigner> Writeable for ChannelMonitorImpl<Signer> {
15421551
(21, self.balances_empty_height, option),
15431552
(23, self.holder_pays_commitment_tx_fee, option),
15441553
(25, self.payment_preimages, required),
1545-
(27, self.first_confirmed_funding_txo, required),
1554+
(27, self.first_negotiated_funding_txo, required),
15461555
(29, self.initial_counterparty_commitment_tx, option),
15471556
(31, self.funding.channel_parameters, required),
15481557
(32, self.pending_funding, optional_vec),
@@ -1726,7 +1735,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
17261735
channel_keys_id,
17271736
holder_revocation_basepoint,
17281737
channel_id,
1729-
first_confirmed_funding_txo: funding_outpoint,
1738+
first_negotiated_funding_txo: funding_outpoint,
17301739

17311740
counterparty_commitment_params,
17321741
their_cur_per_commitment_points: None,
@@ -1785,7 +1794,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
17851794
/// [`Persist`]: crate::chain::chainmonitor::Persist
17861795
pub fn persistence_key(&self) -> MonitorName {
17871796
let inner = self.inner.lock().unwrap();
1788-
let funding_outpoint = inner.first_confirmed_funding_txo;
1797+
let funding_outpoint = inner.first_negotiated_funding_txo;
17891798
let channel_id = inner.channel_id;
17901799
if ChannelId::v1_from_funding_outpoint(funding_outpoint) == channel_id {
17911800
MonitorName::V1Channel(funding_outpoint)
@@ -3770,6 +3779,10 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
37703779
);
37713780
return Err(());
37723781
}
3782+
} else if self.funding.is_splice() {
3783+
// If we've already spliced at least once, we're no longer able to RBF the original
3784+
// funding transaction.
3785+
return Err(());
37733786
}
37743787

37753788
let script_pubkey = channel_parameters.make_funding_redeemscript().to_p2wsh();
@@ -3782,6 +3795,30 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
37823795
Ok(())
37833796
}
37843797

3798+
fn promote_funding(&mut self, new_funding_txid: Txid) -> Result<(), ()> {
3799+
let new_funding = self
3800+
.pending_funding
3801+
.iter_mut()
3802+
.find(|funding| funding.funding_txid() == new_funding_txid);
3803+
if new_funding.is_none() {
3804+
return Err(());
3805+
}
3806+
let mut new_funding = new_funding.unwrap();
3807+
3808+
mem::swap(&mut self.funding, &mut new_funding);
3809+
self.onchain_tx_handler.update_after_renegotiated_funding_locked(
3810+
self.funding.current_holder_commitment_tx.clone(),
3811+
self.funding.prev_holder_commitment_tx.clone(),
3812+
);
3813+
3814+
// The swap above places the previous `FundingScope` into `pending_funding`.
3815+
for funding in self.pending_funding.drain(..) {
3816+
self.outputs_to_watch.remove(&funding.funding_txid());
3817+
}
3818+
3819+
Ok(())
3820+
}
3821+
37853822
#[rustfmt::skip]
37863823
fn update_monitor<B: Deref, F: Deref, L: Deref>(
37873824
&mut self, updates: &ChannelMonitorUpdate, broadcaster: &B, fee_estimator: &F, logger: &WithChannelMonitor<L>
@@ -3900,6 +3937,13 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
39003937
ret = Err(());
39013938
}
39023939
},
3940+
ChannelMonitorUpdateStep::RenegotiatedFundingLocked { funding_txid } => {
3941+
log_trace!(logger, "Updating ChannelMonitor with locked renegotiated funding txid {}", funding_txid);
3942+
if let Err(_) = self.promote_funding(*funding_txid) {
3943+
log_error!(logger, "Unknown funding with txid {} became locked", funding_txid);
3944+
ret = Err(());
3945+
}
3946+
},
39033947
ChannelMonitorUpdateStep::ChannelForceClosed { should_broadcast } => {
39043948
log_trace!(logger, "Updating ChannelMonitor: channel force closed, should broadcast: {}", should_broadcast);
39053949
self.lockdown_from_offchain = true;
@@ -3953,7 +3997,8 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
39533997
|ChannelMonitorUpdateStep::LatestCounterpartyCommitment { .. }
39543998
|ChannelMonitorUpdateStep::ShutdownScript { .. }
39553999
|ChannelMonitorUpdateStep::CommitmentSecret { .. }
3956-
|ChannelMonitorUpdateStep::RenegotiatedFunding { .. } =>
4000+
|ChannelMonitorUpdateStep::RenegotiatedFunding { .. }
4001+
|ChannelMonitorUpdateStep::RenegotiatedFundingLocked { .. } =>
39574002
is_pre_close_update = true,
39584003
// After a channel is closed, we don't communicate with our peer about it, so the
39594004
// only things we will update is getting a new preimage (from a different channel)
@@ -5822,7 +5867,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
58225867
let mut channel_id = None;
58235868
let mut holder_pays_commitment_tx_fee = None;
58245869
let mut payment_preimages_with_info: Option<HashMap<_, _>> = None;
5825-
let mut first_confirmed_funding_txo = RequiredWrapper(None);
5870+
let mut first_negotiated_funding_txo = RequiredWrapper(None);
58265871
let mut channel_parameters = None;
58275872
let mut pending_funding = None;
58285873
read_tlv_fields!(reader, {
@@ -5839,7 +5884,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
58395884
(21, balances_empty_height, option),
58405885
(23, holder_pays_commitment_tx_fee, option),
58415886
(25, payment_preimages_with_info, option),
5842-
(27, first_confirmed_funding_txo, (default_value, outpoint)),
5887+
(27, first_negotiated_funding_txo, (default_value, outpoint)),
58435888
(29, initial_counterparty_commitment_tx, option),
58445889
(31, channel_parameters, (option: ReadableArgs, None)),
58455890
(32, pending_funding, optional_vec),
@@ -5969,7 +6014,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
59696014
channel_keys_id,
59706015
holder_revocation_basepoint,
59716016
channel_id,
5972-
first_confirmed_funding_txo: first_confirmed_funding_txo.0.unwrap(),
6017+
first_negotiated_funding_txo: first_negotiated_funding_txo.0.unwrap(),
59736018

59746019
counterparty_commitment_params,
59756020
their_cur_per_commitment_points,

lightning/src/chain/onchaintx.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1238,6 +1238,15 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
12381238
self.prev_holder_commitment = Some(replace(&mut self.holder_commitment, tx));
12391239
}
12401240

1241+
/// Replaces the current/prev holder commitment transactions spending the currently confirmed
1242+
/// funding outpoint with those spending the new funding outpoint.
1243+
pub(crate) fn update_after_renegotiated_funding_locked(
1244+
&mut self, current: HolderCommitmentTransaction, prev: Option<HolderCommitmentTransaction>,
1245+
) {
1246+
self.holder_commitment = current;
1247+
self.prev_holder_commitment = prev;
1248+
}
1249+
12411250
// Deprecated as of 0.2, only use in cases where it was not previously available.
12421251
pub(crate) fn channel_parameters(&self) -> &ChannelTransactionParameters {
12431252
&self.channel_transaction_parameters

0 commit comments

Comments
 (0)