Skip to content

Commit 6e19d1f

Browse files
committed
Provide preimages to signer
1 parent 9aa786c commit 6e19d1f

File tree

4 files changed

+46
-17
lines changed

4 files changed

+46
-17
lines changed

lightning/src/chain/keysinterface.rs

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ use util::{byte_utils, transaction_utils};
3434
use util::ser::{Writeable, Writer, Readable};
3535

3636
use chain::transaction::OutPoint;
37-
use ln::chan_utils;
37+
use ln::{chan_utils, PaymentPreimage};
3838
use ln::chan_utils::{HTLCOutputInCommitment, make_funding_redeemscript, ChannelPublicKeys, HolderCommitmentTransaction, ChannelTransactionParameters, CommitmentTransaction, ClosingTransaction};
3939
use ln::msgs::UnsignedChannelAnnouncement;
4040
use ln::script::ShutdownScript;
@@ -226,7 +226,14 @@ pub trait BaseSign {
226226
/// secret won't leave us without a broadcastable holder transaction.
227227
/// Policy checks should be implemented in this function, including checking the amount
228228
/// sent to us and checking the HTLCs.
229-
fn validate_holder_commitment(&self, holder_tx: &HolderCommitmentTransaction) -> Result<(), ()>;
229+
///
230+
/// The preimages of outgoing HTLCs that were fulfilled since the last commitment are provided.
231+
/// A validating signer should ensure that an HTLC output is removed only when the matching
232+
/// preimage is provided, or when the value to holder is restored.
233+
///
234+
/// NOTE: all the relevant preimages will be provided, but there may also be additional
235+
/// irrelevant or duplicate preimages.
236+
fn validate_holder_commitment(&self, holder_tx: &HolderCommitmentTransaction, preimages: Vec<PaymentPreimage>) -> Result<(), ()>;
230237
/// Gets the holder's channel public keys and basepoints
231238
fn pubkeys(&self) -> &ChannelPublicKeys;
232239
/// Gets an arbitrary identifier describing the set of keys which are provided back to you in
@@ -240,9 +247,16 @@ pub trait BaseSign {
240247
///
241248
/// Policy checks should be implemented in this function, including checking the amount
242249
/// sent to us and checking the HTLCs.
250+
///
251+
/// The preimages of outgoing HTLCs that were fulfilled since the last commitment are provided.
252+
/// A validating signer should ensure that an HTLC output is removed only when the matching
253+
/// preimage is provided, or when the value to holder is restored.
254+
///
255+
/// NOTE: all the relevant preimages will be provided, but there may also be additional
256+
/// irrelevant or duplicate preimages.
243257
//
244258
// TODO: Document the things someone using this interface should enforce before signing.
245-
fn sign_counterparty_commitment(&self, commitment_tx: &CommitmentTransaction, secp_ctx: &Secp256k1<secp256k1::All>) -> Result<(Signature, Vec<Signature>), ()>;
259+
fn sign_counterparty_commitment(&self, commitment_tx: &CommitmentTransaction, preimages: Vec<PaymentPreimage>, secp_ctx: &Secp256k1<secp256k1::All>) -> Result<(Signature, Vec<Signature>), ()>;
246260
/// Validate the counterparty's revocation.
247261
///
248262
/// This is required in order for the signer to make sure that the state has moved
@@ -601,14 +615,14 @@ impl BaseSign for InMemorySigner {
601615
chan_utils::build_commitment_secret(&self.commitment_seed, idx)
602616
}
603617

604-
fn validate_holder_commitment(&self, _holder_tx: &HolderCommitmentTransaction) -> Result<(), ()> {
618+
fn validate_holder_commitment(&self, _holder_tx: &HolderCommitmentTransaction, _preimages: Vec<PaymentPreimage>) -> Result<(), ()> {
605619
Ok(())
606620
}
607621

608622
fn pubkeys(&self) -> &ChannelPublicKeys { &self.holder_channel_pubkeys }
609623
fn channel_keys_id(&self) -> [u8; 32] { self.channel_keys_id }
610624

611-
fn sign_counterparty_commitment(&self, commitment_tx: &CommitmentTransaction, secp_ctx: &Secp256k1<secp256k1::All>) -> Result<(Signature, Vec<Signature>), ()> {
625+
fn sign_counterparty_commitment(&self, commitment_tx: &CommitmentTransaction, _preimages: Vec<PaymentPreimage>, secp_ctx: &Secp256k1<secp256k1::All>) -> Result<(Signature, Vec<Signature>), ()> {
612626
let trusted_tx = commitment_tx.trust();
613627
let keys = trusted_tx.keys();
614628

lightning/src/ln/channel.rs

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,7 @@ struct CommitmentStats<'a> {
330330
htlcs_included: Vec<(HTLCOutputInCommitment, Option<&'a HTLCSource>)>, // the list of HTLCs (dust HTLCs *included*) which were not ignored when building the transaction
331331
local_balance_msat: u64, // local balance before fees but considering dust limits
332332
remote_balance_msat: u64, // remote balance before fees but considering dust limits
333+
preimages: Vec<PaymentPreimage>, // preimages for successful offered HTLCs since last commitment
333334
}
334335

335336
/// Used when calculating whether we or the remote can afford an additional HTLC.
@@ -1298,6 +1299,8 @@ impl<Signer: Sign> Channel<Signer> {
12981299
}
12991300
}
13001301

1302+
let mut preimages: Vec<PaymentPreimage> = Vec::new();
1303+
13011304
for ref htlc in self.pending_outbound_htlcs.iter() {
13021305
let (include, state_name) = match htlc.state {
13031306
OutboundHTLCState::LocalAnnounced(_) => (generated_by_local, "LocalAnnounced"),
@@ -1307,6 +1310,17 @@ impl<Signer: Sign> Channel<Signer> {
13071310
OutboundHTLCState::AwaitingRemovedRemoteRevoke(_) => (false, "AwaitingRemovedRemoteRevoke"),
13081311
};
13091312

1313+
let preimage_opt = match htlc.state {
1314+
OutboundHTLCState::RemoteRemoved(OutboundHTLCOutcome::Success(p)) => p,
1315+
OutboundHTLCState::AwaitingRemoteRevokeToRemove(OutboundHTLCOutcome::Success(p)) => p,
1316+
OutboundHTLCState::AwaitingRemovedRemoteRevoke(OutboundHTLCOutcome::Success(p)) => p,
1317+
_ => None,
1318+
};
1319+
1320+
if let Some(preimage) = preimage_opt {
1321+
preimages.push(preimage);
1322+
}
1323+
13101324
if include {
13111325
add_htlc_output!(htlc, true, Some(&htlc.source), state_name);
13121326
local_htlc_total_msat += htlc.amount_msat;
@@ -1411,6 +1425,7 @@ impl<Signer: Sign> Channel<Signer> {
14111425
htlcs_included,
14121426
local_balance_msat: value_to_self_msat as u64,
14131427
remote_balance_msat: value_to_remote_msat as u64,
1428+
preimages
14141429
}
14151430
}
14161431

@@ -1882,7 +1897,7 @@ impl<Signer: Sign> Channel<Signer> {
18821897
log_trace!(logger, "Initial counterparty tx for channel {} is: txid {} tx {}",
18831898
log_bytes!(self.channel_id()), counterparty_initial_bitcoin_tx.txid, encode::serialize_hex(&counterparty_initial_bitcoin_tx.transaction));
18841899

1885-
let counterparty_signature = self.holder_signer.sign_counterparty_commitment(&counterparty_initial_commitment_tx, &self.secp_ctx)
1900+
let counterparty_signature = self.holder_signer.sign_counterparty_commitment(&counterparty_initial_commitment_tx, Vec::new(), &self.secp_ctx)
18861901
.map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed".to_owned()))?.0;
18871902

18881903
// We sign "counterparty" commitment transaction, allowing them to broadcast the tx if they wish.
@@ -1936,7 +1951,7 @@ impl<Signer: Sign> Channel<Signer> {
19361951
self.counterparty_funding_pubkey()
19371952
);
19381953

1939-
self.holder_signer.validate_holder_commitment(&holder_commitment_tx)
1954+
self.holder_signer.validate_holder_commitment(&holder_commitment_tx, Vec::new())
19401955
.map_err(|_| ChannelError::Close("Failed to validate our commitment".to_owned()))?;
19411956

19421957
// Now that we're past error-generating stuff, update our local state:
@@ -2013,7 +2028,7 @@ impl<Signer: Sign> Channel<Signer> {
20132028
self.counterparty_funding_pubkey()
20142029
);
20152030

2016-
self.holder_signer.validate_holder_commitment(&holder_commitment_tx)
2031+
self.holder_signer.validate_holder_commitment(&holder_commitment_tx, Vec::new())
20172032
.map_err(|_| ChannelError::Close("Failed to validate our commitment".to_owned()))?;
20182033

20192034

@@ -2682,7 +2697,7 @@ impl<Signer: Sign> Channel<Signer> {
26822697
);
26832698

26842699
let next_per_commitment_point = self.holder_signer.get_per_commitment_point(self.cur_holder_commitment_transaction_number - 1, &self.secp_ctx);
2685-
self.holder_signer.validate_holder_commitment(&holder_commitment_tx)
2700+
self.holder_signer.validate_holder_commitment(&holder_commitment_tx, commitment_stats.preimages)
26862701
.map_err(|_| (None, ChannelError::Close("Failed to validate our commitment".to_owned())))?;
26872702
let per_commitment_secret = self.holder_signer.release_commitment_secret(self.cur_holder_commitment_transaction_number + 1);
26882703

@@ -4529,7 +4544,7 @@ impl<Signer: Sign> Channel<Signer> {
45294544
fn get_outbound_funding_created_signature<L: Deref>(&mut self, logger: &L) -> Result<Signature, ChannelError> where L::Target: Logger {
45304545
let counterparty_keys = self.build_remote_transaction_keys()?;
45314546
let counterparty_initial_commitment_tx = self.build_commitment_transaction(self.cur_counterparty_commitment_transaction_number, &counterparty_keys, false, false, logger).tx;
4532-
Ok(self.holder_signer.sign_counterparty_commitment(&counterparty_initial_commitment_tx, &self.secp_ctx)
4547+
Ok(self.holder_signer.sign_counterparty_commitment(&counterparty_initial_commitment_tx, Vec::new(), &self.secp_ctx)
45334548
.map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed".to_owned()))?.0)
45344549
}
45354550

@@ -4994,7 +5009,7 @@ impl<Signer: Sign> Channel<Signer> {
49945009
htlcs.push(htlc);
49955010
}
49965011

4997-
let res = self.holder_signer.sign_counterparty_commitment(&commitment_stats.tx, &self.secp_ctx)
5012+
let res = self.holder_signer.sign_counterparty_commitment(&commitment_stats.tx, commitment_stats.preimages, &self.secp_ctx)
49985013
.map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed".to_owned()))?;
49995014
signature = res.0;
50005015
htlc_signatures = res.1;

lightning/src/ln/functional_tests.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -730,7 +730,7 @@ fn test_update_fee_that_funder_cannot_afford() {
730730
&mut htlcs,
731731
&local_chan.channel_transaction_parameters.as_counterparty_broadcastable()
732732
);
733-
local_chan_signer.sign_counterparty_commitment(&commitment_tx, &secp_ctx).unwrap()
733+
local_chan_signer.sign_counterparty_commitment(&commitment_tx, Vec::new(), &secp_ctx).unwrap()
734734
};
735735

736736
let commit_signed_msg = msgs::CommitmentSigned {
@@ -1466,7 +1466,7 @@ fn test_fee_spike_violation_fails_htlc() {
14661466
&mut vec![(accepted_htlc_info, ())],
14671467
&local_chan.channel_transaction_parameters.as_counterparty_broadcastable()
14681468
);
1469-
local_chan_signer.sign_counterparty_commitment(&commitment_tx, &secp_ctx).unwrap()
1469+
local_chan_signer.sign_counterparty_commitment(&commitment_tx, Vec::new(), &secp_ctx).unwrap()
14701470
};
14711471

14721472
let commit_signed_msg = msgs::CommitmentSigned {

lightning/src/util/enforcing_trait_impls.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// licenses.
99

1010
use ln::chan_utils::{HTLCOutputInCommitment, ChannelPublicKeys, HolderCommitmentTransaction, CommitmentTransaction, ChannelTransactionParameters, TrustedCommitmentTransaction, ClosingTransaction};
11-
use ln::{chan_utils, msgs};
11+
use ln::{chan_utils, msgs, PaymentPreimage};
1212
use chain::keysinterface::{Sign, InMemorySigner, BaseSign};
1313

1414
use prelude::*;
@@ -102,7 +102,7 @@ impl BaseSign for EnforcingSigner {
102102
self.inner.release_commitment_secret(idx)
103103
}
104104

105-
fn validate_holder_commitment(&self, holder_tx: &HolderCommitmentTransaction) -> Result<(), ()> {
105+
fn validate_holder_commitment(&self, holder_tx: &HolderCommitmentTransaction, _preimages: Vec<PaymentPreimage>) -> Result<(), ()> {
106106
let mut state = self.state.lock().unwrap();
107107
let idx = holder_tx.commitment_number();
108108
assert!(idx == state.last_holder_commitment || idx == state.last_holder_commitment - 1, "expecting to validate the current or next holder commitment - trying {}, current {}", idx, state.last_holder_commitment);
@@ -113,7 +113,7 @@ impl BaseSign for EnforcingSigner {
113113
fn pubkeys(&self) -> &ChannelPublicKeys { self.inner.pubkeys() }
114114
fn channel_keys_id(&self) -> [u8; 32] { self.inner.channel_keys_id() }
115115

116-
fn sign_counterparty_commitment(&self, commitment_tx: &CommitmentTransaction, secp_ctx: &Secp256k1<secp256k1::All>) -> Result<(Signature, Vec<Signature>), ()> {
116+
fn sign_counterparty_commitment(&self, commitment_tx: &CommitmentTransaction, preimages: Vec<PaymentPreimage>, secp_ctx: &Secp256k1<secp256k1::All>) -> Result<(Signature, Vec<Signature>), ()> {
117117
self.verify_counterparty_commitment_tx(commitment_tx, secp_ctx);
118118

119119
{
@@ -129,7 +129,7 @@ impl BaseSign for EnforcingSigner {
129129
state.last_counterparty_commitment = cmp::min(last_commitment_number, actual_commitment_number)
130130
}
131131

132-
Ok(self.inner.sign_counterparty_commitment(commitment_tx, secp_ctx).unwrap())
132+
Ok(self.inner.sign_counterparty_commitment(commitment_tx, preimages, secp_ctx).unwrap())
133133
}
134134

135135
fn validate_counterparty_revocation(&self, idx: u64, _secret: &SecretKey) -> Result<(), ()> {

0 commit comments

Comments
 (0)