Skip to content

Commit c3aed7d

Browse files
committed
Add HTLC/extra data in LocalCommitmentTransaction from construction
1107ab0 introduced some additional metadata, including per-HTLC data in LocalCommitmentTransaction. To keep diff reasonable it did so in ChannelMonitor after the LocalCommitmentTransaction had been constructed and passed over the wall, but there's little reason to do so - we should just be constructing them with the data from the start, filled in by Channel. This cleans up some internal interfaces a bit, slightly reduces some data duplication and moves us one step forward to exposing the guts of LocalCommitmentTransaction publicly in a sensible way.
1 parent f4fef00 commit c3aed7d

File tree

3 files changed

+336
-402
lines changed

3 files changed

+336
-402
lines changed

lightning/src/ln/chan_utils.rs

Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -485,9 +485,8 @@ pub fn build_htlc_transaction(prev_hash: &Sha256dHash, feerate_per_kw: u64, to_s
485485
/// just pass in the SecretKeys required.
486486
pub struct LocalCommitmentTransaction {
487487
tx: Transaction,
488-
//TODO: modify Channel methods to integrate HTLC material at LocalCommitmentTransaction generation to drop Option here
489-
local_keys: Option<TxCreationKeys>,
490-
feerate_per_kw: Option<u64>,
488+
pub(crate) local_keys: TxCreationKeys,
489+
pub(crate) feerate_per_kw: u64,
491490
per_htlc: Vec<(HTLCOutputInCommitment, Option<Signature>, Option<Transaction>)>
492491
}
493492
impl LocalCommitmentTransaction {
@@ -502,21 +501,30 @@ impl LocalCommitmentTransaction {
502501
sequence: 0,
503502
witness: vec![vec![], vec![], vec![]]
504503
};
505-
Self { tx: Transaction {
506-
version: 2,
507-
input: vec![dummy_input],
508-
output: Vec::new(),
509-
lock_time: 0,
510-
},
511-
local_keys: None,
512-
feerate_per_kw: None,
504+
let dummy_key = PublicKey::from_secret_key(&Secp256k1::new(), &SecretKey::from_slice(&[42; 32]).unwrap());
505+
Self {
506+
tx: Transaction {
507+
version: 2,
508+
input: vec![dummy_input],
509+
output: Vec::new(),
510+
lock_time: 0,
511+
},
512+
local_keys: TxCreationKeys {
513+
per_commitment_point: dummy_key.clone(),
514+
revocation_key: dummy_key.clone(),
515+
a_htlc_key: dummy_key.clone(),
516+
b_htlc_key: dummy_key.clone(),
517+
a_delayed_payment_key: dummy_key.clone(),
518+
b_payment_key: dummy_key.clone(),
519+
},
520+
feerate_per_kw: 0,
513521
per_htlc: Vec::new()
514522
}
515523
}
516524

517525
/// Generate a new LocalCommitmentTransaction based on a raw commitment transaction,
518526
/// remote signature and both parties keys
519-
pub(crate) fn new_missing_local_sig(mut tx: Transaction, their_sig: &Signature, our_funding_key: &PublicKey, their_funding_key: &PublicKey) -> LocalCommitmentTransaction {
527+
pub(crate) fn new_missing_local_sig(mut tx: Transaction, their_sig: &Signature, our_funding_key: &PublicKey, their_funding_key: &PublicKey, local_keys: TxCreationKeys, feerate_per_kw: u64, mut htlc_data: Vec<(HTLCOutputInCommitment, Option<Signature>)>) -> LocalCommitmentTransaction {
520528
if tx.input.len() != 1 { panic!("Tried to store a commitment transaction that had input count != 1!"); }
521529
if tx.input[0].witness.len() != 0 { panic!("Tried to store a signed commitment transaction?"); }
522530

@@ -533,9 +541,10 @@ impl LocalCommitmentTransaction {
533541
}
534542

535543
Self { tx,
536-
local_keys: None,
537-
feerate_per_kw: None,
538-
per_htlc: Vec::new()
544+
local_keys,
545+
feerate_per_kw,
546+
// TODO: Avoid the conversion of a Vec created likely just for this:
547+
per_htlc: htlc_data.drain(..).map(|(a, b)| (a, b, None)).collect(),
539548
}
540549
}
541550

@@ -594,33 +603,23 @@ impl LocalCommitmentTransaction {
594603
&self.tx
595604
}
596605

597-
/// Set HTLC cache to generate any local HTLC transaction spending one of htlc ouput
598-
/// from this local commitment transaction
599-
pub(crate) fn set_htlc_cache(&mut self, local_keys: TxCreationKeys, feerate_per_kw: u64, htlc_outputs: Vec<(HTLCOutputInCommitment, Option<Signature>, Option<Transaction>)>) {
600-
self.local_keys = Some(local_keys);
601-
self.feerate_per_kw = Some(feerate_per_kw);
602-
self.per_htlc = htlc_outputs;
603-
}
604-
605606
/// Add local signature for a htlc transaction, do nothing if a cached signed transaction is
606607
/// already present
607608
pub fn add_htlc_sig<T: secp256k1::Signing>(&mut self, htlc_base_key: &SecretKey, htlc_index: u32, preimage: Option<PaymentPreimage>, local_csv: u16, secp_ctx: &Secp256k1<T>) {
608-
if self.local_keys.is_none() || self.feerate_per_kw.is_none() { return; }
609-
let local_keys = self.local_keys.as_ref().unwrap();
610609
let txid = self.txid();
611610
for this_htlc in self.per_htlc.iter_mut() {
612-
if this_htlc.0.transaction_output_index.unwrap() == htlc_index {
611+
if this_htlc.0.transaction_output_index == Some(htlc_index) {
613612
if this_htlc.2.is_some() { return; } // we already have a cached htlc transaction at provided index
614-
let mut htlc_tx = build_htlc_transaction(&txid, self.feerate_per_kw.unwrap(), local_csv, &this_htlc.0, &local_keys.a_delayed_payment_key, &local_keys.revocation_key);
613+
let mut htlc_tx = build_htlc_transaction(&txid, self.feerate_per_kw, local_csv, &this_htlc.0, &self.local_keys.a_delayed_payment_key, &self.local_keys.revocation_key);
615614
if !this_htlc.0.offered && preimage.is_none() { return; } // if we don't have preimage for HTLC-Success, don't try to generate
616615
let htlc_secret = if !this_htlc.0.offered { preimage } else { None }; // if we have a preimage for HTLC-Timeout, don't use it that's likely a duplicate HTLC hash
617616
if this_htlc.1.is_none() { return; } // we don't have any remote signature for this htlc
618617
if htlc_tx.input.len() != 1 { return; }
619618
if htlc_tx.input[0].witness.len() != 0 { return; }
620619

621-
let htlc_redeemscript = get_htlc_redeemscript_with_explicit_keys(&this_htlc.0, &local_keys.a_htlc_key, &local_keys.b_htlc_key, &local_keys.revocation_key);
620+
let htlc_redeemscript = get_htlc_redeemscript_with_explicit_keys(&this_htlc.0, &self.local_keys.a_htlc_key, &self.local_keys.b_htlc_key, &self.local_keys.revocation_key);
622621

623-
if let Ok(our_htlc_key) = derive_private_key(secp_ctx, &local_keys.per_commitment_point, htlc_base_key) {
622+
if let Ok(our_htlc_key) = derive_private_key(secp_ctx, &self.local_keys.per_commitment_point, htlc_base_key) {
624623
let sighash = hash_to_message!(&bip143::SighashComponents::new(&htlc_tx).sighash_all(&htlc_tx.input[0], &htlc_redeemscript, this_htlc.0.amount_msat / 1000)[..]);
625624
let our_sig = secp_ctx.sign(&sighash, &our_htlc_key);
626625

0 commit comments

Comments
 (0)