Skip to content

Commit 00ee0ef

Browse files
authored
Merge pull request #3654 from tankyleo/channel-monitor-updates
[Custom Transactions] Provide Built Counterparty Commitment Transactions To `ChannelMonitor`
2 parents 0e1bbc4 + b8a03cd commit 00ee0ef

File tree

2 files changed

+86
-43
lines changed

2 files changed

+86
-43
lines changed

lightning/src/chain/channelmonitor.rs

+79-28
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,12 @@ pub(crate) enum ChannelMonitorUpdateStep {
544544
to_broadcaster_value_sat: Option<u64>,
545545
to_countersignatory_value_sat: Option<u64>,
546546
},
547+
LatestCounterpartyCommitmentTX {
548+
// The dust and non-dust htlcs for that commitment
549+
htlc_outputs: Vec<(HTLCOutputInCommitment, Option<Box<HTLCSource>>)>,
550+
// Contains only the non-dust htlcs
551+
commitment_tx: CommitmentTransaction,
552+
},
547553
PaymentPreimage {
548554
payment_preimage: PaymentPreimage,
549555
/// If this preimage was from an inbound payment claim, information about the claim should
@@ -571,6 +577,7 @@ impl ChannelMonitorUpdateStep {
571577
match self {
572578
ChannelMonitorUpdateStep::LatestHolderCommitmentTXInfo { .. } => "LatestHolderCommitmentTXInfo",
573579
ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo { .. } => "LatestCounterpartyCommitmentTXInfo",
580+
ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTX { .. } => "LatestCounterpartyCommitmentTX",
574581
ChannelMonitorUpdateStep::PaymentPreimage { .. } => "PaymentPreimage",
575582
ChannelMonitorUpdateStep::CommitmentSecret { .. } => "CommitmentSecret",
576583
ChannelMonitorUpdateStep::ChannelForceClosed { .. } => "ChannelForceClosed",
@@ -609,6 +616,10 @@ impl_writeable_tlv_based_enum_upgradable!(ChannelMonitorUpdateStep,
609616
(5, ShutdownScript) => {
610617
(0, scriptpubkey, required),
611618
},
619+
(6, LatestCounterpartyCommitmentTX) => {
620+
(0, htlc_outputs, required_vec),
621+
(2, commitment_tx, required),
622+
},
612623
);
613624

614625
/// Indicates whether the balance is derived from a cooperative close, a force-close
@@ -1019,6 +1030,11 @@ pub(crate) struct ChannelMonitorImpl<Signer: EcdsaChannelSigner> {
10191030
/// Ordering of tuple data: (their_per_commitment_point, feerate_per_kw, to_broadcaster_sats,
10201031
/// to_countersignatory_sats)
10211032
initial_counterparty_commitment_info: Option<(PublicKey, u32, u64, u64)>,
1033+
/// Initial counterparty commitment transaction
1034+
///
1035+
/// We previously used the field above to re-build the counterparty commitment transaction,
1036+
/// we now provide the transaction outright.
1037+
initial_counterparty_commitment_tx: Option<CommitmentTransaction>,
10221038

10231039
/// The first block height at which we had no remaining claimable balances.
10241040
balances_empty_height: Option<u32>,
@@ -1242,6 +1258,7 @@ impl<Signer: EcdsaChannelSigner> Writeable for ChannelMonitorImpl<Signer> {
12421258
(23, self.holder_pays_commitment_tx_fee, option),
12431259
(25, self.payment_preimages, required),
12441260
(27, self.first_confirmed_funding_txo, required),
1261+
(29, self.initial_counterparty_commitment_tx, option),
12451262
});
12461263

12471264
Ok(())
@@ -1454,6 +1471,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
14541471
best_block,
14551472
counterparty_node_id: counterparty_node_id,
14561473
initial_counterparty_commitment_info: None,
1474+
initial_counterparty_commitment_tx: None,
14571475
balances_empty_height: None,
14581476

14591477
failed_back_htlc_ids: new_hash_set(),
@@ -1486,24 +1504,19 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
14861504
}
14871505

14881506
/// A variant of `Self::provide_latest_counterparty_commitment_tx` used to provide
1489-
/// additional information to the monitor to store in order to recreate the initial
1490-
/// counterparty commitment transaction during persistence (mainly for use in third-party
1491-
/// watchtowers).
1507+
/// the counterparty commitment transaction to the monitor so that the transaction
1508+
/// can be retrieved during the initial persistence of the monitor (mainly for use in
1509+
/// third-party watchtowers).
14921510
///
1493-
/// This is used to provide the counterparty commitment information directly to the monitor
1511+
/// This is used to provide the counterparty commitment transaction directly to the monitor
14941512
/// before the initial persistence of a new channel.
14951513
pub(crate) fn provide_initial_counterparty_commitment_tx<L: Deref>(
1496-
&self, txid: Txid, htlc_outputs: Vec<(HTLCOutputInCommitment, Option<Box<HTLCSource>>)>,
1497-
commitment_number: u64, their_cur_per_commitment_point: PublicKey, feerate_per_kw: u32,
1498-
to_broadcaster_value_sat: u64, to_countersignatory_value_sat: u64, logger: &L,
1499-
)
1500-
where L::Target: Logger
1514+
&self, commitment_tx: CommitmentTransaction, logger: &L,
1515+
) where L::Target: Logger
15011516
{
15021517
let mut inner = self.inner.lock().unwrap();
15031518
let logger = WithChannelMonitor::from_impl(logger, &*inner, None);
1504-
inner.provide_initial_counterparty_commitment_tx(txid,
1505-
htlc_outputs, commitment_number, their_cur_per_commitment_point, feerate_per_kw,
1506-
to_broadcaster_value_sat, to_countersignatory_value_sat, &logger);
1519+
inner.provide_initial_counterparty_commitment_tx(commitment_tx, &logger);
15071520
}
15081521

15091522
/// Informs this monitor of the latest counterparty (ie non-broadcastable) commitment transaction.
@@ -2872,20 +2885,21 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
28722885
}
28732886

28742887
fn provide_initial_counterparty_commitment_tx<L: Deref>(
2875-
&mut self, txid: Txid, htlc_outputs: Vec<(HTLCOutputInCommitment, Option<Box<HTLCSource>>)>,
2876-
commitment_number: u64, their_per_commitment_point: PublicKey, feerate_per_kw: u32,
2877-
to_broadcaster_value: u64, to_countersignatory_value: u64, logger: &WithChannelMonitor<L>,
2888+
&mut self, commitment_tx: CommitmentTransaction, logger: &WithChannelMonitor<L>,
28782889
) where L::Target: Logger {
2879-
self.initial_counterparty_commitment_info = Some((their_per_commitment_point.clone(),
2880-
feerate_per_kw, to_broadcaster_value, to_countersignatory_value));
2890+
// We populate this field for downgrades
2891+
self.initial_counterparty_commitment_info = Some((commitment_tx.per_commitment_point(),
2892+
commitment_tx.feerate_per_kw(), commitment_tx.to_broadcaster_value_sat(), commitment_tx.to_countersignatory_value_sat()));
28812893

28822894
#[cfg(debug_assertions)] {
28832895
let rebuilt_commitment_tx = self.initial_counterparty_commitment_tx().unwrap();
2884-
debug_assert_eq!(rebuilt_commitment_tx.trust().txid(), txid);
2896+
debug_assert_eq!(rebuilt_commitment_tx.trust().txid(), commitment_tx.trust().txid());
28852897
}
28862898

2887-
self.provide_latest_counterparty_commitment_tx(txid, htlc_outputs, commitment_number,
2888-
their_per_commitment_point, logger);
2899+
self.provide_latest_counterparty_commitment_tx(commitment_tx.trust().txid(), Vec::new(), commitment_tx.commitment_number(),
2900+
commitment_tx.per_commitment_point(), logger);
2901+
// Soon, we will only populate this field
2902+
self.initial_counterparty_commitment_tx = Some(commitment_tx);
28892903
}
28902904

28912905
fn provide_latest_counterparty_commitment_tx<L: Deref>(
@@ -3223,10 +3237,17 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
32233237
if self.lockdown_from_offchain { panic!(); }
32243238
self.provide_latest_holder_commitment_tx(commitment_tx.clone(), htlc_outputs.clone(), &claimed_htlcs, nondust_htlc_sources.clone());
32253239
}
3240+
// Soon we will drop the `LatestCounterpartyCommitmentTXInfo` variant in favor of `LatestCounterpartyCommitmentTX`.
3241+
// For now we just add the code to handle the new updates.
3242+
// Next step: in channel, switch channel monitor updates to use the `LatestCounterpartyCommitmentTX` variant.
32263243
ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo { commitment_txid, htlc_outputs, commitment_number, their_per_commitment_point, .. } => {
32273244
log_trace!(logger, "Updating ChannelMonitor with latest counterparty commitment transaction info");
32283245
self.provide_latest_counterparty_commitment_tx(*commitment_txid, htlc_outputs.clone(), *commitment_number, *their_per_commitment_point, logger)
32293246
},
3247+
ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTX { htlc_outputs, commitment_tx } => {
3248+
log_trace!(logger, "Updating ChannelMonitor with latest counterparty commitment transaction info");
3249+
self.provide_latest_counterparty_commitment_tx(commitment_tx.trust().txid(), htlc_outputs.clone(), commitment_tx.commitment_number(), commitment_tx.per_commitment_point(), logger)
3250+
},
32303251
ChannelMonitorUpdateStep::PaymentPreimage { payment_preimage, payment_info } => {
32313252
log_trace!(logger, "Updating ChannelMonitor with payment preimage");
32323253
self.provide_payment_preimage(&PaymentHash(Sha256::hash(&payment_preimage.0[..]).to_byte_array()), &payment_preimage, payment_info, broadcaster, &bounded_fee_estimator, logger)
@@ -3289,6 +3310,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
32893310
match update {
32903311
ChannelMonitorUpdateStep::LatestHolderCommitmentTXInfo { .. }
32913312
|ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo { .. }
3313+
|ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTX { .. }
32923314
|ChannelMonitorUpdateStep::ShutdownScript { .. }
32933315
|ChannelMonitorUpdateStep::CommitmentSecret { .. } =>
32943316
is_pre_close_update = true,
@@ -3419,14 +3441,32 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
34193441
}
34203442

34213443
fn initial_counterparty_commitment_tx(&mut self) -> Option<CommitmentTransaction> {
3422-
let (their_per_commitment_point, feerate_per_kw, to_broadcaster_value,
3423-
to_countersignatory_value) = self.initial_counterparty_commitment_info?;
3424-
let htlc_outputs = vec![];
3425-
3426-
let commitment_tx = self.build_counterparty_commitment_tx(INITIAL_COMMITMENT_NUMBER,
3427-
&their_per_commitment_point, to_broadcaster_value, to_countersignatory_value,
3428-
feerate_per_kw, htlc_outputs);
3429-
Some(commitment_tx)
3444+
self.initial_counterparty_commitment_tx.clone().or_else(|| {
3445+
// This provides forward compatibility; an old monitor will not contain the full
3446+
// transaction; only enough information to rebuild it
3447+
self.initial_counterparty_commitment_info.map(
3448+
|(
3449+
their_per_commitment_point,
3450+
feerate_per_kw,
3451+
to_broadcaster_value,
3452+
to_countersignatory_value,
3453+
)| {
3454+
let htlc_outputs = vec![];
3455+
3456+
let commitment_tx = self.build_counterparty_commitment_tx(
3457+
INITIAL_COMMITMENT_NUMBER,
3458+
&their_per_commitment_point,
3459+
to_broadcaster_value,
3460+
to_countersignatory_value,
3461+
feerate_per_kw,
3462+
htlc_outputs,
3463+
);
3464+
// Take the opportunity to populate this recently introduced field
3465+
self.initial_counterparty_commitment_tx = Some(commitment_tx.clone());
3466+
commitment_tx
3467+
},
3468+
)
3469+
})
34303470
}
34313471

34323472
fn build_counterparty_commitment_tx(
@@ -3454,6 +3494,9 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
34543494

34553495
fn counterparty_commitment_txs_from_update(&self, update: &ChannelMonitorUpdate) -> Vec<CommitmentTransaction> {
34563496
update.updates.iter().filter_map(|update| {
3497+
// Soon we will drop the first branch here in favor of the second.
3498+
// In preparation, we just add the second branch without deleting the first.
3499+
// Next step: in channel, switch channel monitor updates to use the `LatestCounterpartyCommitmentTX` variant.
34573500
match update {
34583501
&ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo { commitment_txid,
34593502
ref htlc_outputs, commitment_number, their_per_commitment_point,
@@ -3473,6 +3516,11 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
34733516

34743517
Some(commitment_tx)
34753518
},
3519+
&ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTX {
3520+
htlc_outputs: _, ref commitment_tx,
3521+
} => {
3522+
Some(commitment_tx.clone())
3523+
},
34763524
_ => None,
34773525
}
34783526
}).collect()
@@ -5043,6 +5091,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
50435091
let mut spendable_txids_confirmed = Some(Vec::new());
50445092
let mut counterparty_fulfilled_htlcs = Some(new_hash_map());
50455093
let mut initial_counterparty_commitment_info = None;
5094+
let mut initial_counterparty_commitment_tx = None;
50465095
let mut balances_empty_height = None;
50475096
let mut channel_id = None;
50485097
let mut holder_pays_commitment_tx_fee = None;
@@ -5063,6 +5112,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
50635112
(23, holder_pays_commitment_tx_fee, option),
50645113
(25, payment_preimages_with_info, option),
50655114
(27, first_confirmed_funding_txo, (default_value, funding_info.0)),
5115+
(29, initial_counterparty_commitment_tx, option),
50665116
});
50675117
if let Some(payment_preimages_with_info) = payment_preimages_with_info {
50685118
if payment_preimages_with_info.len() != payment_preimages.len() {
@@ -5166,6 +5216,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
51665216
best_block,
51675217
counterparty_node_id: counterparty_node_id.unwrap(),
51685218
initial_counterparty_commitment_info,
5219+
initial_counterparty_commitment_tx,
51695220
balances_empty_height,
51705221
failed_back_htlc_ids: new_hash_set(),
51715222
})))

lightning/src/ln/channel.rs

+7-15
Original file line numberDiff line numberDiff line change
@@ -2062,7 +2062,7 @@ trait InitialRemoteCommitmentReceiver<SP: Deref> where SP::Target: SignerProvide
20622062

20632063
fn initial_commitment_signed<L: Deref>(
20642064
&mut self, channel_id: ChannelId, counterparty_signature: Signature, holder_commitment_point: &mut HolderCommitmentPoint,
2065-
counterparty_commitment_number: u64, best_block: BestBlock, signer_provider: &SP, logger: &L,
2065+
best_block: BestBlock, signer_provider: &SP, logger: &L,
20662066
) -> Result<(ChannelMonitor<<SP::Target as SignerProvider>::EcdsaSigner>, CommitmentTransaction), ChannelError>
20672067
where
20682068
L::Target: Logger
@@ -2140,14 +2140,7 @@ trait InitialRemoteCommitmentReceiver<SP: Deref> where SP::Target: SignerProvide
21402140
funding_redeemscript.clone(), funding.get_value_satoshis(),
21412141
obscure_factor,
21422142
holder_commitment_tx, best_block, context.counterparty_node_id, context.channel_id());
2143-
channel_monitor.provide_initial_counterparty_commitment_tx(
2144-
counterparty_initial_bitcoin_tx.txid, Vec::new(),
2145-
counterparty_commitment_number,
2146-
context.counterparty_cur_commitment_point.unwrap(),
2147-
counterparty_initial_commitment_tx.feerate_per_kw(),
2148-
counterparty_initial_commitment_tx.to_broadcaster_value_sat(),
2149-
counterparty_initial_commitment_tx.to_countersignatory_value_sat(),
2150-
logger);
2143+
channel_monitor.provide_initial_counterparty_commitment_tx(counterparty_initial_commitment_tx.clone(), logger);
21512144

21522145
self.context_mut().cur_counterparty_commitment_transaction_number -= 1;
21532146

@@ -5681,8 +5674,7 @@ impl<SP: Deref> FundedChannel<SP> where
56815674
self.context.assert_no_commitment_advancement(holder_commitment_point.transaction_number(), "initial commitment_signed");
56825675

56835676
let (channel_monitor, _) = self.initial_commitment_signed(
5684-
self.context.channel_id(), msg.signature, holder_commitment_point,
5685-
self.context.cur_counterparty_commitment_transaction_number, best_block, signer_provider, logger)?;
5677+
self.context.channel_id(), msg.signature, holder_commitment_point, best_block, signer_provider, logger)?;
56865678
self.holder_commitment_point = *holder_commitment_point;
56875679

56885680
log_info!(logger, "Received initial commitment_signed from peer for channel {}", &self.context.channel_id());
@@ -8743,6 +8735,8 @@ impl<SP: Deref> FundedChannel<SP> where
87438735
self.context.latest_monitor_update_id += 1;
87448736
let monitor_update = ChannelMonitorUpdate {
87458737
update_id: self.context.latest_monitor_update_id,
8738+
// Soon, we will switch this to `LatestCounterpartyCommitmentTX`,
8739+
// and provide the full commit tx instead of the information needed to rebuild it.
87468740
updates: vec![ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo {
87478741
commitment_txid: counterparty_commitment_txid,
87488742
htlc_outputs: htlcs.clone(),
@@ -9465,8 +9459,7 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
94659459

94669460
let (channel_monitor, _) = match self.initial_commitment_signed(
94679461
self.context.channel_id(), msg.signature,
9468-
&mut holder_commitment_point, self.context.cur_counterparty_commitment_transaction_number,
9469-
best_block, signer_provider, logger
9462+
&mut holder_commitment_point, best_block, signer_provider, logger
94709463
) {
94719464
Ok(channel_monitor) => channel_monitor,
94729465
Err(err) => return Err((self, err)),
@@ -9735,8 +9728,7 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
97359728

97369729
let (channel_monitor, counterparty_initial_commitment_tx) = match self.initial_commitment_signed(
97379730
ChannelId::v1_from_funding_outpoint(funding_txo), msg.signature,
9738-
&mut holder_commitment_point, self.context.cur_counterparty_commitment_transaction_number,
9739-
best_block, signer_provider, logger
9731+
&mut holder_commitment_point, best_block, signer_provider, logger
97409732
) {
97419733
Ok(channel_monitor) => channel_monitor,
97429734
Err(err) => return Err((self, err)),

0 commit comments

Comments
 (0)