Skip to content

Commit 4592add

Browse files
committed
Provide inbound HTLC preimages to the EcdsaChannelSigner
The VLS signer has a desire to see preimages for resolved forwarded HTLCs when they are first claimed by us, even if that claim was for the inbound edge (where claiming strictly increases our balance). Luckily, providing that information is rather trivial, which we do here. Fixes #2356
1 parent 2659a23 commit 4592add

File tree

3 files changed

+30
-16
lines changed

3 files changed

+30
-16
lines changed

lightning/src/ln/channel.rs

+18-8
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,8 @@ struct CommitmentStats<'a> {
479479
htlcs_included: Vec<(HTLCOutputInCommitment, Option<&'a HTLCSource>)>, // the list of HTLCs (dust HTLCs *included*) which were not ignored when building the transaction
480480
local_balance_msat: u64, // local balance before fees but considering dust limits
481481
remote_balance_msat: u64, // remote balance before fees but considering dust limits
482-
preimages: Vec<PaymentPreimage>, // preimages for successful offered HTLCs since last commitment
482+
outbound_htlc_preimages: Vec<PaymentPreimage>, // preimages for successful offered HTLCs since last commitment
483+
inbound_htlc_preimages: Vec<PaymentPreimage>, // preimages for successful received HTLCs since last commitment
483484
}
484485

485486
/// Used when calculating whether we or the remote can afford an additional HTLC.
@@ -1393,6 +1394,8 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
13931394
}
13941395
}
13951396

1397+
let mut inbound_htlc_preimages: Vec<PaymentPreimage> = Vec::new();
1398+
13961399
for ref htlc in self.pending_inbound_htlcs.iter() {
13971400
let (include, state_name) = match htlc.state {
13981401
InboundHTLCState::RemoteAnnounced(_) => (!generated_by_local, "RemoteAnnounced"),
@@ -1410,7 +1413,8 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
14101413
match &htlc.state {
14111414
&InboundHTLCState::LocalRemoved(ref reason) => {
14121415
if generated_by_local {
1413-
if let &InboundHTLCRemovalReason::Fulfill(_) = reason {
1416+
if let &InboundHTLCRemovalReason::Fulfill(preimage) = reason {
1417+
inbound_htlc_preimages.push(preimage);
14141418
value_to_self_msat_offset += htlc.amount_msat as i64;
14151419
}
14161420
}
@@ -1420,7 +1424,8 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
14201424
}
14211425
}
14221426

1423-
let mut preimages: Vec<PaymentPreimage> = Vec::new();
1427+
1428+
let mut outbound_htlc_preimages: Vec<PaymentPreimage> = Vec::new();
14241429

14251430
for ref htlc in self.pending_outbound_htlcs.iter() {
14261431
let (include, state_name) = match htlc.state {
@@ -1439,7 +1444,7 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
14391444
};
14401445

14411446
if let Some(preimage) = preimage_opt {
1442-
preimages.push(preimage);
1447+
outbound_htlc_preimages.push(preimage);
14431448
}
14441449

14451450
if include {
@@ -1545,7 +1550,8 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
15451550
htlcs_included,
15461551
local_balance_msat: value_to_self_msat as u64,
15471552
remote_balance_msat: value_to_remote_msat as u64,
1548-
preimages
1553+
inbound_htlc_preimages,
1554+
outbound_htlc_preimages,
15491555
}
15501556
}
15511557

@@ -3208,7 +3214,7 @@ impl<SP: Deref> Channel<SP> where
32083214
self.context.counterparty_funding_pubkey()
32093215
);
32103216

3211-
self.context.holder_signer.as_ref().validate_holder_commitment(&holder_commitment_tx, commitment_stats.preimages)
3217+
self.context.holder_signer.as_ref().validate_holder_commitment(&holder_commitment_tx, commitment_stats.outgoing_htlc_preimages)
32123218
.map_err(|_| ChannelError::Close("Failed to validate our commitment".to_owned()))?;
32133219

32143220
// Update state now that we've passed all the can-fail calls...
@@ -5709,8 +5715,12 @@ impl<SP: Deref> Channel<SP> where
57095715
htlcs.push(htlc);
57105716
}
57115717

5712-
let res = ecdsa.sign_counterparty_commitment(&commitment_stats.tx, commitment_stats.preimages, &self.context.secp_ctx)
5713-
.map_err(|_| ChannelError::Ignore("Failed to get signatures for new commitment_signed".to_owned()))?;
5718+
let res = ecdsa.sign_counterparty_commitment(
5719+
&commitment_stats.tx,
5720+
commitment_stats.incoming_htlc_preimages,
5721+
commitment_stats.outgoing_htlc_preimages,
5722+
&self.context.secp_ctx,
5723+
).map_err(|_| ChannelError::Ignore("Failed to get signatures for new commitment_signed".to_owned()))?;
57145724
signature = res.0;
57155725
htlc_signatures = res.1;
57165726

lightning/src/sign/ecdsa.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,18 @@ pub trait EcdsaChannelSigner: ChannelSigner {
2929
/// Policy checks should be implemented in this function, including checking the amount
3030
/// sent to us and checking the HTLCs.
3131
///
32-
/// The preimages of outgoing HTLCs that were fulfilled since the last commitment are provided.
33-
/// A validating signer should ensure that an HTLC output is removed only when the matching
34-
/// preimage is provided, or when the value to holder is restored.
32+
/// The preimages of outgoing and incoming HTLCs that were fulfilled since the last commitment
33+
/// are provided. A validating signer should ensure that an outgoing HTLC output is removed
34+
/// only when the matching preimage is provided and after the corresponding incoming HTLC has
35+
/// been removed for forwarded payments.
3536
///
3637
/// Note that all the relevant preimages will be provided, but there may also be additional
3738
/// irrelevant or duplicate preimages.
3839
//
3940
// TODO: Document the things someone using this interface should enforce before signing.
4041
fn sign_counterparty_commitment(&self, commitment_tx: &CommitmentTransaction,
41-
preimages: Vec<PaymentPreimage>, secp_ctx: &Secp256k1<secp256k1::All>
42+
incoming_preimages: Vec<PaymentPreimage>, outgoing_preimages: Vec<PaymentPreimage>,
43+
secp_ctx: &Secp256k1<secp256k1::All>,
4244
) -> Result<(Signature, Vec<Signature>), ()>;
4345
/// Validate the counterparty's revocation.
4446
///

lightning/src/sign/taproot.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,18 @@ pub trait TaprootChannelSigner: ChannelSigner {
2727
/// Policy checks should be implemented in this function, including checking the amount
2828
/// sent to us and checking the HTLCs.
2929
///
30-
/// The preimages of outgoing HTLCs that were fulfilled since the last commitment are provided.
31-
/// A validating signer should ensure that an HTLC output is removed only when the matching
32-
/// preimage is provided, or when the value to holder is restored.
30+
/// The preimages of outgoing and incoming HTLCs that were fulfilled since the last commitment
31+
/// are provided. A validating signer should ensure that an outgoing HTLC output is removed
32+
/// only when the matching preimage is provided and after the corresponding incoming HTLC has
33+
/// been removed for forwarded payments.
3334
///
3435
/// Note that all the relevant preimages will be provided, but there may also be additional
3536
/// irrelevant or duplicate preimages.
3637
//
3738
// TODO: Document the things someone using this interface should enforce before signing.
3839
fn partially_sign_counterparty_commitment(&self, counterparty_nonce: PublicNonce,
39-
commitment_tx: &CommitmentTransaction, preimages: Vec<PaymentPreimage>,
40+
commitment_tx: &CommitmentTransaction,
41+
incoming_preimages: Vec<PaymentPreimage>, outgoing_preimages: Vec<PaymentPreimage>,
4042
secp_ctx: &Secp256k1<secp256k1::All>,
4143
) -> Result<(PartialSignatureWithNonce, Vec<Signature>), ()>;
4244

0 commit comments

Comments
 (0)