Skip to content

Commit c79b64d

Browse files
committed
Introduce LatestCounterpartyCommitment monitor update variant
This new variant is a backwards-incompatible successor to `LatestCounterpartyCommitmentTXInfo` that is capable of handling counterparty commitment updates while a splice is pending. Since all counterparty commitment candidates share the same set of non-dust and dust HTLCs (though each non-dust HTLC can have differing output indices), we can share the same set of HTLC source data across all candidates. Unfortunately, each `FundingScope` tracks its own set of `counterparty_claimable_outpoints`, which includes the HTLC source data (though only for the current and previous counterparty commitments), so we end up duplicating it (both in memory and on disk) temporarily.
1 parent 6c78160 commit c79b64d

File tree

2 files changed

+159
-83
lines changed

2 files changed

+159
-83
lines changed

lightning/src/chain/channelmonitor.rs

Lines changed: 111 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -649,11 +649,9 @@ pub(crate) enum ChannelMonitorUpdateStep {
649649
to_broadcaster_value_sat: Option<u64>,
650650
to_countersignatory_value_sat: Option<u64>,
651651
},
652-
LatestCounterpartyCommitmentTX {
653-
// The dust and non-dust htlcs for that commitment
654-
htlc_outputs: Vec<(HTLCOutputInCommitment, Option<Box<HTLCSource>>)>,
655-
// Contains only the non-dust htlcs
656-
commitment_tx: CommitmentTransaction,
652+
LatestCounterpartyCommitment {
653+
commitment_txs: Vec<CommitmentTransaction>,
654+
htlc_data: CommitmentHTLCData,
657655
},
658656
PaymentPreimage {
659657
payment_preimage: PaymentPreimage,
@@ -689,7 +687,7 @@ impl ChannelMonitorUpdateStep {
689687
ChannelMonitorUpdateStep::LatestHolderCommitmentTXInfo { .. } => "LatestHolderCommitmentTXInfo",
690688
ChannelMonitorUpdateStep::LatestHolderCommitment { .. } => "LatestHolderCommitment",
691689
ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo { .. } => "LatestCounterpartyCommitmentTXInfo",
692-
ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTX { .. } => "LatestCounterpartyCommitmentTX",
690+
ChannelMonitorUpdateStep::LatestCounterpartyCommitment { .. } => "LatestCounterpartyCommitment",
693691
ChannelMonitorUpdateStep::PaymentPreimage { .. } => "PaymentPreimage",
694692
ChannelMonitorUpdateStep::CommitmentSecret { .. } => "CommitmentSecret",
695693
ChannelMonitorUpdateStep::ChannelForceClosed { .. } => "ChannelForceClosed",
@@ -729,9 +727,9 @@ impl_writeable_tlv_based_enum_upgradable!(ChannelMonitorUpdateStep,
729727
(5, ShutdownScript) => {
730728
(0, scriptpubkey, required),
731729
},
732-
(6, LatestCounterpartyCommitmentTX) => {
733-
(0, htlc_outputs, required_vec),
734-
(2, commitment_tx, required),
730+
(6, LatestCounterpartyCommitment) => {
731+
(1, commitment_txs, required_vec),
732+
(3, htlc_data, required),
735733
},
736734
(8, LatestHolderCommitment) => {
737735
(1, commitment_txs, required_vec),
@@ -1847,34 +1845,29 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
18471845
///
18481846
/// This is used to provide the counterparty commitment transaction directly to the monitor
18491847
/// before the initial persistence of a new channel.
1850-
pub(crate) fn provide_initial_counterparty_commitment_tx<L: Deref>(
1851-
&self, commitment_tx: CommitmentTransaction, logger: &L,
1852-
) where
1853-
L::Target: Logger,
1854-
{
1848+
pub(crate) fn provide_initial_counterparty_commitment_tx(
1849+
&self, commitment_tx: CommitmentTransaction,
1850+
) {
18551851
let mut inner = self.inner.lock().unwrap();
1856-
let logger = WithChannelMonitor::from_impl(logger, &*inner, None);
1857-
inner.provide_initial_counterparty_commitment_tx(commitment_tx, &logger);
1852+
inner.provide_initial_counterparty_commitment_tx(commitment_tx);
18581853
}
18591854

18601855
/// Informs this monitor of the latest counterparty (ie non-broadcastable) commitment transaction.
18611856
/// The monitor watches for it to be broadcasted and then uses the HTLC information (and
18621857
/// possibly future revocation/preimage information) to claim outputs where possible.
18631858
/// We cache also the mapping hash:commitment number to lighten pruning of old preimages by watchtowers.
18641859
#[cfg(test)]
1865-
#[rustfmt::skip]
1866-
fn provide_latest_counterparty_commitment_tx<L: Deref>(
1867-
&self,
1868-
txid: Txid,
1869-
htlc_outputs: Vec<(HTLCOutputInCommitment, Option<Box<HTLCSource>>)>,
1870-
commitment_number: u64,
1871-
their_per_commitment_point: PublicKey,
1872-
logger: &L,
1873-
) where L::Target: Logger {
1860+
fn provide_latest_counterparty_commitment_tx(
1861+
&self, txid: Txid, htlc_outputs: Vec<(HTLCOutputInCommitment, Option<Box<HTLCSource>>)>,
1862+
commitment_number: u64, their_per_commitment_point: PublicKey,
1863+
) {
18741864
let mut inner = self.inner.lock().unwrap();
1875-
let logger = WithChannelMonitor::from_impl(logger, &*inner, None);
18761865
inner.provide_latest_counterparty_commitment_tx(
1877-
txid, htlc_outputs, commitment_number, their_per_commitment_point, &logger)
1866+
txid,
1867+
htlc_outputs,
1868+
commitment_number,
1869+
their_per_commitment_point,
1870+
)
18781871
}
18791872

18801873
#[cfg(test)]
@@ -1883,7 +1876,9 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
18831876
&self, holder_commitment_tx: HolderCommitmentTransaction,
18841877
htlc_outputs: &[(HTLCOutputInCommitment, Option<Signature>, Option<HTLCSource>)],
18851878
) {
1886-
self.inner.lock().unwrap().provide_latest_holder_commitment_tx(holder_commitment_tx, htlc_outputs, &Vec::new(), Vec::new())
1879+
self.inner.lock().unwrap().provide_latest_holder_commitment_tx(
1880+
holder_commitment_tx, htlc_outputs, &Vec::new(), Vec::new()
1881+
).unwrap()
18871882
}
18881883

18891884
/// This is used to provide payment preimage(s) out-of-band during startup without updating the
@@ -3259,9 +3254,9 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
32593254
}
32603255

32613256
#[rustfmt::skip]
3262-
fn provide_initial_counterparty_commitment_tx<L: Deref>(
3263-
&mut self, commitment_tx: CommitmentTransaction, logger: &WithChannelMonitor<L>,
3264-
) where L::Target: Logger {
3257+
fn provide_initial_counterparty_commitment_tx(
3258+
&mut self, commitment_tx: CommitmentTransaction,
3259+
) {
32653260
// We populate this field for downgrades
32663261
self.initial_counterparty_commitment_info = Some((commitment_tx.per_commitment_point(),
32673262
commitment_tx.feerate_per_kw(), commitment_tx.to_broadcaster_value_sat(), commitment_tx.to_countersignatory_value_sat()));
@@ -3272,17 +3267,16 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
32723267
}
32733268

32743269
self.provide_latest_counterparty_commitment_tx(commitment_tx.trust().txid(), Vec::new(), commitment_tx.commitment_number(),
3275-
commitment_tx.per_commitment_point(), logger);
3270+
commitment_tx.per_commitment_point());
32763271
// Soon, we will only populate this field
32773272
self.initial_counterparty_commitment_tx = Some(commitment_tx);
32783273
}
32793274

32803275
#[rustfmt::skip]
3281-
fn provide_latest_counterparty_commitment_tx<L: Deref>(
3282-
&mut self, txid: Txid,
3283-
htlc_outputs: Vec<(HTLCOutputInCommitment, Option<Box<HTLCSource>>)>,
3284-
commitment_number: u64, their_per_commitment_point: PublicKey, logger: &WithChannelMonitor<L>,
3285-
) where L::Target: Logger {
3276+
fn provide_latest_counterparty_commitment_tx(
3277+
&mut self, txid: Txid, htlc_outputs: Vec<(HTLCOutputInCommitment, Option<Box<HTLCSource>>)>,
3278+
commitment_number: u64, their_per_commitment_point: PublicKey,
3279+
) {
32863280
// TODO: Encrypt the htlc_outputs data with the single-hash of the commitment transaction
32873281
// so that a remote monitor doesn't learn anything unless there is a malicious close.
32883282
// (only maybe, sadly we cant do the same for local info, as we need to be aware of
@@ -3291,11 +3285,11 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
32913285
self.counterparty_hash_commitment_number.insert(htlc.payment_hash, commitment_number);
32923286
}
32933287

3294-
log_trace!(logger, "Tracking new counterparty commitment transaction with txid {} at commitment number {} with {} HTLC outputs", txid, commitment_number, htlc_outputs.len());
32953288
self.funding.prev_counterparty_commitment_txid = self.funding.current_counterparty_commitment_txid.take();
32963289
self.funding.current_counterparty_commitment_txid = Some(txid);
3297-
self.funding.counterparty_claimable_outpoints.insert(txid, htlc_outputs.clone());
3290+
self.funding.counterparty_claimable_outpoints.insert(txid, htlc_outputs);
32983291
self.current_counterparty_commitment_number = commitment_number;
3292+
32993293
//TODO: Merge this into the other per-counterparty-transaction output storage stuff
33003294
match self.their_cur_per_commitment_points {
33013295
Some(old_points) => {
@@ -3317,6 +3311,58 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
33173311
}
33183312
}
33193313

3314+
fn update_counterparty_commitment_data(
3315+
&mut self, commitment_txs: &[CommitmentTransaction], htlc_data: &CommitmentHTLCData,
3316+
) -> Result<(), &'static str> {
3317+
self.verify_matching_commitment_transactions(commitment_txs.iter())?;
3318+
3319+
let htlcs_for_commitment = |commitment: &CommitmentTransaction| {
3320+
let mut nondust_htlcs = commitment.nondust_htlcs().iter();
3321+
let mut sources = htlc_data.nondust_htlc_sources.iter();
3322+
let nondust_htlcs = core::iter::from_fn(move || {
3323+
let htlc = nondust_htlcs.next()?.clone();
3324+
let source = (!htlc.offered).then(|| {
3325+
let source = sources
3326+
.next()
3327+
.expect("Every offered non-dust HTLC should have a corresponding source")
3328+
.clone();
3329+
Box::new(source)
3330+
});
3331+
Some((htlc, source))
3332+
});
3333+
3334+
let dust_htlcs = htlc_data
3335+
.dust_htlcs
3336+
.clone()
3337+
.into_iter()
3338+
.map(|(htlc, source)| (htlc, source.map(|source| Box::new(source))));
3339+
3340+
nondust_htlcs.chain(dust_htlcs).collect::<Vec<_>>()
3341+
};
3342+
3343+
let current_funding_commitment_tx = commitment_txs.first().unwrap();
3344+
self.provide_latest_counterparty_commitment_tx(
3345+
current_funding_commitment_tx.trust().txid(),
3346+
htlcs_for_commitment(current_funding_commitment_tx),
3347+
current_funding_commitment_tx.commitment_number(),
3348+
current_funding_commitment_tx.per_commitment_point(),
3349+
);
3350+
3351+
for (pending_funding, commitment_tx) in
3352+
self.pending_funding.iter_mut().zip(commitment_txs.iter().skip(1))
3353+
{
3354+
let commitment_txid = commitment_tx.trust().txid();
3355+
pending_funding.prev_counterparty_commitment_txid =
3356+
pending_funding.current_counterparty_commitment_txid.take();
3357+
pending_funding.current_counterparty_commitment_txid = Some(commitment_txid);
3358+
pending_funding
3359+
.counterparty_claimable_outpoints
3360+
.insert(commitment_txid, htlcs_for_commitment(commitment_tx));
3361+
}
3362+
3363+
Ok(())
3364+
}
3365+
33203366
/// Informs this monitor of the latest holder (ie broadcastable) commitment transaction. The
33213367
/// monitor watches for timeouts and may broadcast it if we approach such a timeout. Thus, it
33223368
/// is important that any clones of this channel monitor (including remote clones) by kept
@@ -3851,14 +3897,24 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
38513897
},
38523898
// Soon we will drop the `LatestCounterpartyCommitmentTXInfo` variant in favor of `LatestCounterpartyCommitment`.
38533899
// For now we just add the code to handle the new updates.
3854-
// Next step: in channel, switch channel monitor updates to use the `LatestCounterpartyCommitmentTX` variant.
3900+
// Next step: in channel, switch channel monitor updates to use the `LatestCounterpartyCommitment` variant.
38553901
ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo { commitment_txid, htlc_outputs, commitment_number, their_per_commitment_point, .. } => {
38563902
log_trace!(logger, "Updating ChannelMonitor with latest counterparty commitment transaction info");
3857-
self.provide_latest_counterparty_commitment_tx(*commitment_txid, htlc_outputs.clone(), *commitment_number, *their_per_commitment_point, logger)
3903+
if self.pending_funding.is_empty() {
3904+
self.provide_latest_counterparty_commitment_tx(*commitment_txid, htlc_outputs.clone(), *commitment_number, *their_per_commitment_point)
3905+
} else {
3906+
log_error!(logger, "Received unexpected non-splice counterparty commitment monitor update");
3907+
ret = Err(());
3908+
}
38583909
},
3859-
ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTX { htlc_outputs, commitment_tx } => {
3860-
log_trace!(logger, "Updating ChannelMonitor with latest counterparty commitment transaction info");
3861-
self.provide_latest_counterparty_commitment_tx(commitment_tx.trust().txid(), htlc_outputs.clone(), commitment_tx.commitment_number(), commitment_tx.per_commitment_point(), logger)
3910+
ChannelMonitorUpdateStep::LatestCounterpartyCommitment {
3911+
commitment_txs, htlc_data,
3912+
} => {
3913+
log_trace!(logger, "Updating ChannelMonitor with latest counterparty commitment");
3914+
if let Err(e) = self.update_counterparty_commitment_data(commitment_txs, htlc_data) {
3915+
log_error!(logger, "Failed updating latest counterparty commitment state: {}", e);
3916+
ret = Err(());
3917+
}
38623918
},
38633919
ChannelMonitorUpdateStep::PaymentPreimage { payment_preimage, payment_info } => {
38643920
log_trace!(logger, "Updating ChannelMonitor with payment preimage");
@@ -3934,7 +3990,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
39343990
ChannelMonitorUpdateStep::LatestHolderCommitmentTXInfo { .. }
39353991
|ChannelMonitorUpdateStep::LatestHolderCommitment { .. }
39363992
|ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo { .. }
3937-
|ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTX { .. }
3993+
|ChannelMonitorUpdateStep::LatestCounterpartyCommitment { .. }
39383994
|ChannelMonitorUpdateStep::ShutdownScript { .. }
39393995
|ChannelMonitorUpdateStep::CommitmentSecret { .. }
39403996
|ChannelMonitorUpdateStep::RenegotiatedFunding { .. } =>
@@ -4094,7 +4150,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
40944150
update.updates.iter().filter_map(|update| {
40954151
// Soon we will drop the first branch here in favor of the second.
40964152
// In preparation, we just add the second branch without deleting the first.
4097-
// Next step: in channel, switch channel monitor updates to use the `LatestCounterpartyCommitmentTX` variant.
4153+
// Next step: in channel, switch channel monitor updates to use the `LatestCounterpartyCommitment` variant.
40984154
match update {
40994155
&ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo { commitment_txid,
41004156
ref htlc_outputs, commitment_number, their_per_commitment_point,
@@ -4112,19 +4168,17 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
41124168

41134169
debug_assert_eq!(commitment_tx.trust().txid(), commitment_txid);
41144170

4115-
Some(commitment_tx)
4171+
Some(vec![commitment_tx])
41164172
},
4117-
&ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTX {
4118-
htlc_outputs: _, ref commitment_tx,
4119-
} => {
4120-
Some(commitment_tx.clone())
4173+
&ChannelMonitorUpdateStep::LatestCounterpartyCommitment { ref commitment_txs, .. } => {
4174+
Some(commitment_txs.clone())
41214175
},
41224176
&ChannelMonitorUpdateStep::RenegotiatedFunding { ref counterparty_commitment_tx, .. } => {
4123-
Some(counterparty_commitment_tx.clone())
4177+
Some(vec![counterparty_commitment_tx.clone()])
41244178
},
41254179
_ => None,
41264180
}
4127-
}).collect()
4181+
}).flatten().collect()
41284182
}
41294183

41304184
#[rustfmt::skip]
@@ -6248,9 +6302,9 @@ mod tests {
62486302
monitor.provide_latest_holder_commitment_tx(dummy_commitment_tx.clone(),
62496303
&nondust_htlcs.iter().map(|htlc| (htlc.clone(), Some(dummy_sig), Some(dummy_source.clone()))).collect::<Vec<_>>());
62506304
monitor.provide_latest_counterparty_commitment_tx(Txid::from_byte_array(Sha256::hash(b"1").to_byte_array()),
6251-
preimages_slice_to_htlc_outputs!(preimages[5..15]), 281474976710655, dummy_key, &logger);
6305+
preimages_slice_to_htlc_outputs!(preimages[5..15]), 281474976710655, dummy_key);
62526306
monitor.provide_latest_counterparty_commitment_tx(Txid::from_byte_array(Sha256::hash(b"2").to_byte_array()),
6253-
preimages_slice_to_htlc_outputs!(preimages[15..20]), 281474976710654, dummy_key, &logger);
6307+
preimages_slice_to_htlc_outputs!(preimages[15..20]), 281474976710654, dummy_key);
62546308
for &(ref preimage, ref hash) in preimages.iter() {
62556309
let bounded_fee_estimator = LowerBoundedFeeEstimator::new(&fee_estimator);
62566310
monitor.provide_payment_preimage_unsafe_legacy(
@@ -6267,7 +6321,7 @@ mod tests {
62676321
test_preimages_exist!(&preimages[15..20], monitor);
62686322

62696323
monitor.provide_latest_counterparty_commitment_tx(Txid::from_byte_array(Sha256::hash(b"3").to_byte_array()),
6270-
preimages_slice_to_htlc_outputs!(preimages[17..20]), 281474976710653, dummy_key, &logger);
6324+
preimages_slice_to_htlc_outputs!(preimages[17..20]), 281474976710653, dummy_key);
62716325

62726326
// Now provide a further secret, pruning preimages 15-17
62736327
secret[0..32].clone_from_slice(&<Vec<u8>>::from_hex("c7518c8ae4660ed02894df8976fa1a3659c1a8b4b5bec0c4b872abeba4cb8964").unwrap());
@@ -6277,7 +6331,7 @@ mod tests {
62776331
test_preimages_exist!(&preimages[17..20], monitor);
62786332

62796333
monitor.provide_latest_counterparty_commitment_tx(Txid::from_byte_array(Sha256::hash(b"4").to_byte_array()),
6280-
preimages_slice_to_htlc_outputs!(preimages[18..20]), 281474976710652, dummy_key, &logger);
6334+
preimages_slice_to_htlc_outputs!(preimages[18..20]), 281474976710652, dummy_key);
62816335

62826336
// Now update holder commitment tx info, pruning only element 18 as we still care about the
62836337
// previous commitment tx's preimages too

0 commit comments

Comments
 (0)