Skip to content

Commit c409b6c

Browse files
devrandomnaumenkogs
authored andcommitted
ChannelKeys - provide to_self_delay alongside the remote channel pubkeys
In the phase 2 signer, we will construct the commitment transaction inside the signer. In preparation, provide needed channel related data.
1 parent b417c16 commit c409b6c

File tree

5 files changed

+98
-57
lines changed

5 files changed

+98
-57
lines changed

lightning/src/chain/keysinterface.rs

Lines changed: 73 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ pub enum SpendableOutputDescriptor {
6969
///
7070
/// To derive the remote_revocation_pubkey provided here (which is used in the witness
7171
/// script generation), you must pass the remote revocation_basepoint (which appears in the
72-
/// call to ChannelKeys::set_remote_channel_pubkeys) and the provided per_commitment point
72+
/// call to ChannelKeys::on_accept) and the provided per_commitment point
7373
/// to chan_utils::derive_public_revocation_key.
7474
///
7575
/// The witness script which is hashed and included in the output script_pubkey may be
@@ -223,7 +223,7 @@ pub trait ChannelKeys : Send+Clone {
223223
// TODO: Document the things someone using this interface should enforce before signing.
224224
// TODO: Add more input vars to enable better checking (preferably removing commitment_tx and
225225
// making the callee generate it via some util function we expose)!
226-
fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, keys: &TxCreationKeys, htlcs: &[&HTLCOutputInCommitment], to_self_delay: u16, secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()>;
226+
fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, keys: &TxCreationKeys, htlcs: &[&HTLCOutputInCommitment], secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()>;
227227

228228
/// Create a signature for a local commitment transaction. This will only ever be called with
229229
/// the same local_commitment_tx (or a copy thereof), though there are currently no guarantees
@@ -254,7 +254,7 @@ pub trait ChannelKeys : Send+Clone {
254254
/// (implying they were considered dust at the time the commitment transaction was negotiated),
255255
/// a corresponding None should be included in the return value. All other positions in the
256256
/// return value must contain a signature.
257-
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>>, ()>;
257+
fn sign_local_commitment_htlc_transactions<T: secp256k1::Signing + secp256k1::Verification>(&self, local_commitment_tx: &LocalCommitmentTransaction, secp_ctx: &Secp256k1<T>) -> Result<Vec<Option<Signature>>, ()>;
258258

259259
/// Create a signature for the given input in a transaction spending an HTLC or commitment
260260
/// transaction output when our counterparty broadcasts an old state.
@@ -274,11 +274,7 @@ pub trait ChannelKeys : Send+Clone {
274274
/// htlc holds HTLC elements (hash, timelock) if the output being spent is a HTLC output, thus
275275
/// changing the format of the witness script (which is committed to in the BIP 143
276276
/// signatures).
277-
///
278-
/// on_remote_tx_csv is the relative lock-time that that our counterparty would have to set on
279-
/// their transaction were they to spend the same output. It is included in the witness script
280-
/// and thus committed to in the BIP 143 signature.
281-
fn sign_justice_transaction<T: secp256k1::Signing + secp256k1::Verification>(&self, justice_tx: &Transaction, input: usize, amount: u64, per_commitment_key: &SecretKey, htlc: &Option<HTLCOutputInCommitment>, on_remote_tx_csv: u16, secp_ctx: &Secp256k1<T>) -> Result<Signature, ()>;
277+
fn sign_justice_transaction<T: secp256k1::Signing + secp256k1::Verification>(&self, justice_tx: &Transaction, input: usize, amount: u64, per_commitment_key: &SecretKey, htlc: &Option<HTLCOutputInCommitment>, secp_ctx: &Secp256k1<T>) -> Result<Signature, ()>;
282278

283279
/// Create a signature for a claiming transaction for a HTLC output on a remote commitment
284280
/// transaction, either offered or received.
@@ -313,11 +309,13 @@ pub trait ChannelKeys : Send+Clone {
313309
/// protocol.
314310
fn sign_channel_announcement<T: secp256k1::Signing>(&self, msg: &msgs::UnsignedChannelAnnouncement, secp_ctx: &Secp256k1<T>) -> Result<Signature, ()>;
315311

316-
/// Set the remote channel basepoints. This is done immediately on incoming channels
317-
/// and as soon as the channel is accepted on outgoing channels.
312+
/// Set the remote channel basepoints and remote/local to_self_delay.
313+
/// This is done immediately on incoming channels and as soon as the channel is accepted on outgoing channels.
314+
///
315+
/// We bind local_to_self_delay late here for API convenience.
318316
///
319317
/// Will be called before any signatures are applied.
320-
fn set_remote_channel_pubkeys(&mut self, channel_points: &ChannelPublicKeys);
318+
fn on_accept(&mut self, channel_points: &ChannelPublicKeys, remote_to_self_delay: u16, local_to_self_delay: u16);
321319
}
322320

323321
/// A trait to describe an object which can get user secrets and key material.
@@ -342,6 +340,25 @@ pub trait KeysInterface: Send + Sync {
342340
fn get_channel_id(&self) -> [u8; 32];
343341
}
344342

343+
#[derive(Clone)]
344+
/// Holds late-bound channel data.
345+
/// This data is available after the channel is known to be accepted, either
346+
/// when receiving an open_channel for an inbound channel or when
347+
/// receiving accept_channel for an outbound channel.
348+
struct AcceptedChannelData {
349+
/// Remote public keys and base points
350+
remote_channel_pubkeys: ChannelPublicKeys,
351+
/// The to_self_delay value specified by our counterparty and applied on locally-broadcastable
352+
/// transactions, ie the amount of time that we have to wait to recover our funds if we
353+
/// broadcast a transaction. You'll likely want to pass this to the
354+
/// ln::chan_utils::build*_transaction functions when signing local transactions.
355+
remote_to_self_delay: u16,
356+
/// The to_self_delay value specified by us and applied on transactions broadcastable
357+
/// by our counterparty, ie the amount of time that they have to wait to recover their funds
358+
/// if they broadcast a transaction.
359+
local_to_self_delay: u16,
360+
}
361+
345362
#[derive(Clone)]
346363
/// A simple implementation of ChannelKeys that just keeps the private keys in memory.
347364
pub struct InMemoryChannelKeys {
@@ -359,8 +376,8 @@ pub struct InMemoryChannelKeys {
359376
pub commitment_seed: [u8; 32],
360377
/// Local public keys and basepoints
361378
pub(crate) local_channel_pubkeys: ChannelPublicKeys,
362-
/// Remote public keys and base points
363-
pub(crate) remote_channel_pubkeys: Option<ChannelPublicKeys>,
379+
/// Remote public keys and remote/local to_self_delay, populated on channel acceptance
380+
accepted_channel_data: Option<AcceptedChannelData>,
364381
/// The total value of this channel
365382
channel_value_satoshis: u64,
366383
/// Key derivation parameters
@@ -392,7 +409,7 @@ impl InMemoryChannelKeys {
392409
commitment_seed,
393410
channel_value_satoshis,
394411
local_channel_pubkeys,
395-
remote_channel_pubkeys: None,
412+
accepted_channel_data: None,
396413
key_derivation_params,
397414
}
398415
}
@@ -413,7 +430,22 @@ impl InMemoryChannelKeys {
413430
}
414431
}
415432

416-
fn remote_pubkeys<'a>(&'a self) -> &'a ChannelPublicKeys { self.remote_channel_pubkeys.as_ref().unwrap() }
433+
/// Remote pubkeys.
434+
/// Will panic if on_accept wasn't called.
435+
pub fn remote_pubkeys(&self) -> &ChannelPublicKeys { &self.accepted_channel_data.as_ref().unwrap().remote_channel_pubkeys }
436+
437+
/// The to_self_delay value specified by our counterparty and applied on locally-broadcastable
438+
/// transactions, ie the amount of time that we have to wait to recover our funds if we
439+
/// broadcast a transaction. You'll likely want to pass this to the
440+
/// ln::chan_utils::build*_transaction functions when signing local transactions.
441+
/// Will panic if on_accept wasn't called.
442+
pub fn remote_to_self_delay(&self) -> u16 { self.accepted_channel_data.as_ref().unwrap().remote_to_self_delay }
443+
444+
/// The to_self_delay value specified by us and applied on transactions broadcastable
445+
/// by our counterparty, ie the amount of time that they have to wait to recover their funds
446+
/// if they broadcast a transaction.
447+
/// Will panic if on_accept wasn't called.
448+
pub fn local_to_self_delay(&self) -> u16 { self.accepted_channel_data.as_ref().unwrap().local_to_self_delay }
417449
}
418450

419451
impl ChannelKeys for InMemoryChannelKeys {
@@ -429,12 +461,12 @@ impl ChannelKeys for InMemoryChannelKeys {
429461
fn pubkeys(&self) -> &ChannelPublicKeys { &self.local_channel_pubkeys }
430462
fn key_derivation_params(&self) -> (u64, u64) { self.key_derivation_params }
431463

432-
fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, keys: &TxCreationKeys, htlcs: &[&HTLCOutputInCommitment], to_self_delay: u16, secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()> {
464+
fn sign_remote_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, feerate_per_kw: u32, commitment_tx: &Transaction, keys: &TxCreationKeys, htlcs: &[&HTLCOutputInCommitment], secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()> {
433465
if commitment_tx.input.len() != 1 { return Err(()); }
434466

435467
let funding_pubkey = PublicKey::from_secret_key(secp_ctx, &self.funding_key);
436-
let remote_channel_pubkeys = self.remote_channel_pubkeys.as_ref().expect("must set remote channel pubkeys before signing");
437-
let channel_funding_redeemscript = make_funding_redeemscript(&funding_pubkey, &remote_channel_pubkeys.funding_pubkey);
468+
let accepted_data = self.accepted_channel_data.as_ref().expect("must accept before signing");
469+
let channel_funding_redeemscript = make_funding_redeemscript(&funding_pubkey, &accepted_data.remote_channel_pubkeys.funding_pubkey);
438470

439471
let commitment_sighash = hash_to_message!(&bip143::SighashComponents::new(&commitment_tx).sighash_all(&commitment_tx.input[0], &channel_funding_redeemscript, self.channel_value_satoshis)[..]);
440472
let commitment_sig = secp_ctx.sign(&commitment_sighash, &self.funding_key);
@@ -444,7 +476,7 @@ impl ChannelKeys for InMemoryChannelKeys {
444476
let mut htlc_sigs = Vec::with_capacity(htlcs.len());
445477
for ref htlc in htlcs {
446478
if let Some(_) = htlc.transaction_output_index {
447-
let htlc_tx = chan_utils::build_htlc_transaction(&commitment_txid, feerate_per_kw, to_self_delay, htlc, &keys.a_delayed_payment_key, &keys.revocation_key);
479+
let htlc_tx = chan_utils::build_htlc_transaction(&commitment_txid, feerate_per_kw, accepted_data.local_to_self_delay, htlc, &keys.a_delayed_payment_key, &keys.revocation_key);
448480
let htlc_redeemscript = chan_utils::get_htlc_redeemscript(&htlc, &keys);
449481
let htlc_sighash = hash_to_message!(&bip143::SighashComponents::new(&htlc_tx).sighash_all(&htlc_tx.input[0], &htlc_redeemscript, htlc.amount_msat / 1000)[..]);
450482
let our_htlc_key = match chan_utils::derive_private_key(&secp_ctx, &keys.per_commitment_point, &self.htlc_base_key) {
@@ -460,26 +492,27 @@ impl ChannelKeys for InMemoryChannelKeys {
460492

461493
fn sign_local_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, local_commitment_tx: &LocalCommitmentTransaction, secp_ctx: &Secp256k1<T>) -> Result<Signature, ()> {
462494
let funding_pubkey = PublicKey::from_secret_key(secp_ctx, &self.funding_key);
463-
let remote_channel_pubkeys = self.remote_channel_pubkeys.as_ref().expect("must set remote channel pubkeys before signing");
464-
let channel_funding_redeemscript = make_funding_redeemscript(&funding_pubkey, &remote_channel_pubkeys.funding_pubkey);
495+
let remote_channel_data = self.accepted_channel_data.as_ref().expect("must accept before signing");
496+
let channel_funding_redeemscript = make_funding_redeemscript(&funding_pubkey, &remote_channel_data.remote_channel_pubkeys.funding_pubkey);
465497

466498
Ok(local_commitment_tx.get_local_sig(&self.funding_key, &channel_funding_redeemscript, self.channel_value_satoshis, secp_ctx))
467499
}
468500

469501
#[cfg(test)]
470502
fn unsafe_sign_local_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, local_commitment_tx: &LocalCommitmentTransaction, secp_ctx: &Secp256k1<T>) -> Result<Signature, ()> {
471503
let funding_pubkey = PublicKey::from_secret_key(secp_ctx, &self.funding_key);
472-
let remote_channel_pubkeys = self.remote_channel_pubkeys.as_ref().expect("must set remote channel pubkeys before signing");
504+
let remote_channel_pubkeys = &self.accepted_channel_data.as_ref().expect("must accept before signing").remote_channel_pubkeys;
473505
let channel_funding_redeemscript = make_funding_redeemscript(&funding_pubkey, &remote_channel_pubkeys.funding_pubkey);
474506

475507
Ok(local_commitment_tx.get_local_sig(&self.funding_key, &channel_funding_redeemscript, self.channel_value_satoshis, secp_ctx))
476508
}
477509

478-
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>>, ()> {
510+
fn sign_local_commitment_htlc_transactions<T: secp256k1::Signing + secp256k1::Verification>(&self, local_commitment_tx: &LocalCommitmentTransaction, secp_ctx: &Secp256k1<T>) -> Result<Vec<Option<Signature>>, ()> {
511+
let local_csv = self.accepted_channel_data.as_ref().unwrap().remote_to_self_delay;
479512
local_commitment_tx.get_htlc_sigs(&self.htlc_base_key, local_csv, secp_ctx)
480513
}
481514

482-
fn sign_justice_transaction<T: secp256k1::Signing + secp256k1::Verification>(&self, justice_tx: &Transaction, input: usize, amount: u64, per_commitment_key: &SecretKey, htlc: &Option<HTLCOutputInCommitment>, on_remote_tx_csv: u16, secp_ctx: &Secp256k1<T>) -> Result<Signature, ()> {
515+
fn sign_justice_transaction<T: secp256k1::Signing + secp256k1::Verification>(&self, justice_tx: &Transaction, input: usize, amount: u64, per_commitment_key: &SecretKey, htlc: &Option<HTLCOutputInCommitment>, secp_ctx: &Secp256k1<T>) -> Result<Signature, ()> {
483516
let revocation_key = match chan_utils::derive_private_revocation_key(&secp_ctx, &per_commitment_key, &self.revocation_base_key) {
484517
Ok(revocation_key) => revocation_key,
485518
Err(_) => return Err(())
@@ -504,7 +537,7 @@ impl ChannelKeys for InMemoryChannelKeys {
504537
Ok(remote_delayedpubkey) => remote_delayedpubkey,
505538
Err(_) => return Err(())
506539
};
507-
chan_utils::get_revokeable_redeemscript(&revocation_pubkey, on_remote_tx_csv, &remote_delayedpubkey)
540+
chan_utils::get_revokeable_redeemscript(&revocation_pubkey, self.local_to_self_delay(), &remote_delayedpubkey)
508541
};
509542
let sighash_parts = bip143::SighashComponents::new(&justice_tx);
510543
let sighash = hash_to_message!(&sighash_parts.sighash_all(&justice_tx.input[input], &witness_script, amount)[..]);
@@ -532,9 +565,9 @@ impl ChannelKeys for InMemoryChannelKeys {
532565
if closing_tx.input[0].witness.len() != 0 { return Err(()); }
533566
if closing_tx.output.len() > 2 { return Err(()); }
534567

535-
let remote_channel_pubkeys = self.remote_channel_pubkeys.as_ref().expect("must set remote channel pubkeys before signing");
536568
let funding_pubkey = PublicKey::from_secret_key(secp_ctx, &self.funding_key);
537-
let channel_funding_redeemscript = make_funding_redeemscript(&funding_pubkey, &remote_channel_pubkeys.funding_pubkey);
569+
let remote_channel_data = self.accepted_channel_data.as_ref().expect("must accept before signing");
570+
let channel_funding_redeemscript = make_funding_redeemscript(&funding_pubkey, &remote_channel_data.remote_channel_pubkeys.funding_pubkey);
538571

539572
let sighash = hash_to_message!(&bip143::SighashComponents::new(closing_tx)
540573
.sighash_all(&closing_tx.input[0], &channel_funding_redeemscript, self.channel_value_satoshis)[..]);
@@ -546,12 +579,19 @@ impl ChannelKeys for InMemoryChannelKeys {
546579
Ok(secp_ctx.sign(&msghash, &self.funding_key))
547580
}
548581

549-
fn set_remote_channel_pubkeys(&mut self, channel_pubkeys: &ChannelPublicKeys) {
550-
assert!(self.remote_channel_pubkeys.is_none(), "Already set remote channel pubkeys");
551-
self.remote_channel_pubkeys = Some(channel_pubkeys.clone());
582+
fn on_accept(&mut self, channel_pubkeys: &ChannelPublicKeys, remote_to_self_delay: u16, local_to_self_delay: u16) {
583+
assert!(self.accepted_channel_data.is_none(), "Already accepted");
584+
self.accepted_channel_data = Some(AcceptedChannelData {
585+
remote_channel_pubkeys: channel_pubkeys.clone(),
586+
remote_to_self_delay,
587+
local_to_self_delay,
588+
});
552589
}
553590
}
554591

592+
impl_writeable!(AcceptedChannelData, 0,
593+
{ remote_channel_pubkeys, remote_to_self_delay, local_to_self_delay });
594+
555595
impl Writeable for InMemoryChannelKeys {
556596
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), Error> {
557597
self.funding_key.write(writer)?;
@@ -560,7 +600,7 @@ impl Writeable for InMemoryChannelKeys {
560600
self.delayed_payment_base_key.write(writer)?;
561601
self.htlc_base_key.write(writer)?;
562602
self.commitment_seed.write(writer)?;
563-
self.remote_channel_pubkeys.write(writer)?;
603+
self.accepted_channel_data.write(writer)?;
564604
self.channel_value_satoshis.write(writer)?;
565605
self.key_derivation_params.0.write(writer)?;
566606
self.key_derivation_params.1.write(writer)?;
@@ -577,7 +617,7 @@ impl Readable for InMemoryChannelKeys {
577617
let delayed_payment_base_key = Readable::read(reader)?;
578618
let htlc_base_key = Readable::read(reader)?;
579619
let commitment_seed = Readable::read(reader)?;
580-
let remote_channel_pubkeys = Readable::read(reader)?;
620+
let remote_channel_data = Readable::read(reader)?;
581621
let channel_value_satoshis = Readable::read(reader)?;
582622
let secp_ctx = Secp256k1::signing_only();
583623
let local_channel_pubkeys =
@@ -596,7 +636,7 @@ impl Readable for InMemoryChannelKeys {
596636
commitment_seed,
597637
channel_value_satoshis,
598638
local_channel_pubkeys,
599-
remote_channel_pubkeys,
639+
accepted_channel_data: remote_channel_data,
600640
key_derivation_params: (params_1, params_2),
601641
})
602642
}

0 commit comments

Comments
 (0)