Skip to content

Commit 8fb50f2

Browse files
authored
Merge pull request #598 from TheBlueMatt/2020-04-559-cleanups
Clean up ChannelKeys API
2 parents 4dc0dd1 + 03316cd commit 8fb50f2

File tree

7 files changed

+421
-229
lines changed

7 files changed

+421
-229
lines changed

lightning/src/chain/keysinterface.rs

Lines changed: 42 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ use util::ser::{Writeable, Writer, Readable};
2525

2626
use ln::chan_utils;
2727
use ln::chan_utils::{TxCreationKeys, HTLCOutputInCommitment, make_funding_redeemscript, ChannelPublicKeys, LocalCommitmentTransaction};
28-
use ln::channelmanager::PaymentPreimage;
2928
use ln::msgs;
3029

3130
use std::sync::Arc;
@@ -185,11 +184,11 @@ pub trait KeysInterface: Send + Sync {
185184
/// Readable/Writable to serialize out a unique reference to this set of keys so
186185
/// that you can serialize the full ChannelManager object.
187186
///
188-
/// (TODO: We shouldn't require that, and should have an API to get them at deser time, due mostly
189-
/// to the possibility of reentrancy issues by calling the user's code during our deserialization
190-
/// routine).
191-
/// TODO: We should remove Clone by instead requesting a new ChannelKeys copy when we create
192-
/// ChannelMonitors instead of expecting to clone the one out of the Channel into the monitors.
187+
// (TODO: We shouldn't require that, and should have an API to get them at deser time, due mostly
188+
// to the possibility of reentrancy issues by calling the user's code during our deserialization
189+
// routine).
190+
// TODO: We should remove Clone by instead requesting a new ChannelKeys copy when we create
191+
// ChannelMonitors instead of expecting to clone the one out of the Channel into the monitors.
193192
pub trait ChannelKeys : Send+Clone {
194193
/// Gets the private key for the anchor tx
195194
fn funding_key<'a>(&'a self) -> &'a SecretKey;
@@ -210,32 +209,42 @@ pub trait ChannelKeys : Send+Clone {
210209
/// Create a signature for a remote commitment transaction and associated HTLC transactions.
211210
///
212211
/// Note that if signing fails or is rejected, the channel will be force-closed.
213-
///
214-
/// TODO: Document the things someone using this interface should enforce before signing.
215-
/// TODO: Add more input vars to enable better checking (preferably removing commitment_tx and
216-
/// making the callee generate it via some util function we expose)!
212+
//
213+
// TODO: Document the things someone using this interface should enforce before signing.
214+
// TODO: Add more input vars to enable better checking (preferably removing commitment_tx and
215+
// making the callee generate it via some util function we expose)!
217216
fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u64, commitment_tx: &Transaction, keys: &TxCreationKeys, htlcs: &[&HTLCOutputInCommitment], to_self_delay: u16, secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()>;
218217

219-
/// Create a signature for a local commitment transaction
220-
///
221-
/// TODO: Document the things someone using this interface should enforce before signing.
222-
/// TODO: Add more input vars to enable better checking (preferably removing commitment_tx and
223-
/// TODO: Ensure test-only version doesn't enforce uniqueness of signature when it's enforced in this method
224-
/// making the callee generate it via some util function we expose)!
225-
fn sign_local_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, local_commitment_tx: &mut LocalCommitmentTransaction, secp_ctx: &Secp256k1<T>);
218+
/// Create a signature for a local commitment transaction. This will only ever be called with
219+
/// the same local_commitment_tx (or a copy thereof), though there are currently no guarantees
220+
/// that it will not be called multiple times.
221+
//
222+
// TODO: Document the things someone using this interface should enforce before signing.
223+
// TODO: Add more input vars to enable better checking (preferably removing commitment_tx and
224+
fn sign_local_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, local_commitment_tx: &LocalCommitmentTransaction, secp_ctx: &Secp256k1<T>) -> Result<Signature, ()>;
225+
226+
/// Same as sign_local_commitment, but exists only for tests to get access to local commitment
227+
/// transactions which will be broadcasted later, after the channel has moved on to a newer
228+
/// state. Thus, needs its own method as sign_local_commitment may enforce that we only ever
229+
/// get called once.
230+
#[cfg(test)]
231+
fn unsafe_sign_local_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, local_commitment_tx: &LocalCommitmentTransaction, secp_ctx: &Secp256k1<T>) -> Result<Signature, ()>;
226232

227-
/// Create a signature for a local commitment transaction without enforcing one-time signing.
233+
/// Create a signature for each HTLC transaction spending a local commitment transaction.
228234
///
229-
/// Testing revocation logic by our test framework needs to sign multiple local commitment
230-
/// transactions. This unsafe test-only version doesn't enforce one-time signing security
231-
/// requirement.
232-
#[cfg(test)]
233-
fn unsafe_sign_local_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, local_commitment_tx: &mut LocalCommitmentTransaction, secp_ctx: &Secp256k1<T>);
235+
/// Unlike sign_local_commitment, this may be called multiple times with *different*
236+
/// local_commitment_tx values. While this will never be called with a revoked
237+
/// local_commitment_tx, it is possible that it is called with the second-latest
238+
/// local_commitment_tx (only if we haven't yet revoked it) if some watchtower/secondary
239+
/// ChannelMonitor decided to broadcast before it had been updated to the latest.
240+
///
241+
/// Either an Err should be returned, or a Vec with one entry for each HTLC which exists in
242+
/// local_commitment_tx. For those HTLCs which have transaction_output_index set to None
243+
/// (implying they were considered dust at the time the commitment transaction was negotiated),
244+
/// a corresponding None should be included in the return value. All other positions in the
245+
/// return value must contain a signature.
246+
fn sign_local_commitment_htlc_transactions<T: secp256k1::Signing + secp256k1::Verification>(&self, local_commitment_tx: &LocalCommitmentTransaction, local_csv: u16, secp_ctx: &Secp256k1<T>) -> Result<Vec<Option<Signature>>, ()>;
234247

235-
/// Signs a transaction created by build_htlc_transaction. If the transaction is an
236-
/// HTLC-Success transaction, preimage must be set!
237-
/// TODO: should be merged with sign_local_commitment as a slice of HTLC transactions to sign
238-
fn sign_htlc_transaction<T: secp256k1::Signing>(&self, local_commitment_tx: &mut LocalCommitmentTransaction, htlc_index: u32, preimage: Option<PaymentPreimage>, local_csv: u16, secp_ctx: &Secp256k1<T>);
239248
/// Create a signature for a (proposed) closing transaction.
240249
///
241250
/// Note that, due to rounding, there may be one "missing" satoshi, and either party may have
@@ -363,25 +372,25 @@ impl ChannelKeys for InMemoryChannelKeys {
363372
Ok((commitment_sig, htlc_sigs))
364373
}
365374

366-
fn sign_local_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, local_commitment_tx: &mut LocalCommitmentTransaction, secp_ctx: &Secp256k1<T>) {
375+
fn sign_local_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, local_commitment_tx: &LocalCommitmentTransaction, secp_ctx: &Secp256k1<T>) -> Result<Signature, ()> {
367376
let funding_pubkey = PublicKey::from_secret_key(secp_ctx, &self.funding_key);
368377
let remote_channel_pubkeys = self.remote_channel_pubkeys.as_ref().expect("must set remote channel pubkeys before signing");
369378
let channel_funding_redeemscript = make_funding_redeemscript(&funding_pubkey, &remote_channel_pubkeys.funding_pubkey);
370379

371-
local_commitment_tx.add_local_sig(&self.funding_key, &channel_funding_redeemscript, self.channel_value_satoshis, secp_ctx);
380+
Ok(local_commitment_tx.get_local_sig(&self.funding_key, &channel_funding_redeemscript, self.channel_value_satoshis, secp_ctx))
372381
}
373382

374383
#[cfg(test)]
375-
fn unsafe_sign_local_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, local_commitment_tx: &mut LocalCommitmentTransaction, secp_ctx: &Secp256k1<T>) {
384+
fn unsafe_sign_local_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, local_commitment_tx: &LocalCommitmentTransaction, secp_ctx: &Secp256k1<T>) -> Result<Signature, ()> {
376385
let funding_pubkey = PublicKey::from_secret_key(secp_ctx, &self.funding_key);
377386
let remote_channel_pubkeys = self.remote_channel_pubkeys.as_ref().expect("must set remote channel pubkeys before signing");
378387
let channel_funding_redeemscript = make_funding_redeemscript(&funding_pubkey, &remote_channel_pubkeys.funding_pubkey);
379388

380-
local_commitment_tx.add_local_sig(&self.funding_key, &channel_funding_redeemscript, self.channel_value_satoshis, secp_ctx);
389+
Ok(local_commitment_tx.get_local_sig(&self.funding_key, &channel_funding_redeemscript, self.channel_value_satoshis, secp_ctx))
381390
}
382391

383-
fn sign_htlc_transaction<T: secp256k1::Signing>(&self, local_commitment_tx: &mut LocalCommitmentTransaction, htlc_index: u32, preimage: Option<PaymentPreimage>, local_csv: u16, secp_ctx: &Secp256k1<T>) {
384-
local_commitment_tx.add_htlc_sig(&self.htlc_base_key, htlc_index, preimage, local_csv, secp_ctx);
392+
fn sign_local_commitment_htlc_transactions<T: secp256k1::Signing + secp256k1::Verification>(&self, local_commitment_tx: &LocalCommitmentTransaction, local_csv: u16, secp_ctx: &Secp256k1<T>) -> Result<Vec<Option<Signature>>, ()> {
393+
local_commitment_tx.get_htlc_sigs(&self.htlc_base_key, local_csv, secp_ctx)
385394
}
386395

387396
fn sign_closing_transaction<T: secp256k1::Signing>(&self, closing_tx: &Transaction, secp_ctx: &Secp256k1<T>) -> Result<Signature, ()> {

0 commit comments

Comments
 (0)