Skip to content

Commit 863b95c

Browse files
committed
make ChannelStaticInfo party-agnostic
1 parent a016204 commit 863b95c

File tree

2 files changed

+74
-59
lines changed

2 files changed

+74
-59
lines changed

lightning/src/ln/chan_utils.rs

Lines changed: 53 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -556,16 +556,40 @@ pub fn build_htlc_transaction(prev_hash: &Txid, feerate_per_kw: u32, contest_del
556556

557557
/// Static channel fields used to build transactions given per-commitment fields (CommitmentTransactionInfo)
558558
pub struct ChannelStaticInfo {
559-
/// Broadcaster public keys
560-
pub broadcaster_pubkeys: ChannelPublicKeys,
561-
/// Counter-signatory public keys
562-
pub countersignatory_pubkeys: ChannelPublicKeys,
559+
/// Holder public keys
560+
pub holder_pubkeys: ChannelPublicKeys,
561+
/// Counter-party public keys
562+
pub counterparty_pubkeys: ChannelPublicKeys,
563+
/// The contest delay selected by the holder
564+
pub holder_selected_contest_delay: u16,
565+
/// The contest delay selected by the counterparty
566+
pub counterparty_selected_contest_delay: u16,
563567
/// The funding outpoint
564568
pub funding_outpoint: OutPoint,
565-
/// The contest delay selected by the countersignatory
566-
pub contest_delay: u16,
567-
/// Whether the channel is outbound from the point of view of the broadcaster
568-
pub is_outbound: bool,
569+
/// Whether the channel is outbound from the point of view of the holder
570+
pub is_outbound_from_holder: bool,
571+
}
572+
573+
impl ChannelStaticInfo {
574+
/// Get the pubkeys for the selected side and the opposing side
575+
pub fn pubkeys(&self, holder: bool) -> (&ChannelPublicKeys, &ChannelPublicKeys) {
576+
if holder {
577+
(&self.holder_pubkeys, &self.counterparty_pubkeys)
578+
} else {
579+
(&self.counterparty_pubkeys, &self.holder_pubkeys)
580+
}
581+
}
582+
583+
/// Get the contest delay applicable to the selected side's transactions.
584+
/// Note that the contest delay was selected by the opposite party.
585+
pub fn contest_delay(&self, holder: bool) -> u16 {
586+
if holder { self.counterparty_selected_contest_delay } else { self.holder_selected_contest_delay }
587+
}
588+
589+
/// Whether the channel is outbound from the perspective of the selected party
590+
pub fn is_outbound(&self, holder: bool) -> bool {
591+
return if holder { self.is_outbound_from_holder } else { !self.is_outbound_from_holder };
592+
}
569593
}
570594

571595
/// This class tracks the information needed to build a holder's commitment transaction and to actually
@@ -581,7 +605,7 @@ pub struct HolderCommitmentTransactionInfo {
581605

582606
impl HolderCommitmentTransactionInfo {
583607
pub(crate) fn to_holder_commitment_tx<T: secp256k1::Signing + secp256k1::Verification>(&self, channel_static_info: &ChannelStaticInfo, secp_ctx: &Secp256k1<T>) -> HolderCommitmentTransaction {
584-
self.info.to_holder_commitment_tx(self.counterparty_sig, self.htlcs_with_sig.clone(), channel_static_info, secp_ctx)
608+
self.info.to_holder_commitment_tx(true, self.counterparty_sig, self.htlcs_with_sig.clone(), channel_static_info, secp_ctx)
585609
}
586610
}
587611

@@ -652,12 +676,13 @@ impl CommitmentTransactionInfo {
652676
/// is_outbound is true if the channel is outbound from the point of view of the broadcaster
653677
pub fn build<T: secp256k1::Signing + secp256k1::Verification>(
654678
&self,
679+
holder: bool,
655680
channel_static_info: &ChannelStaticInfo,
656681
secp_ctx: &Secp256k1<T>,
657682
) -> Result<(bitcoin::Transaction, Vec<HTLCOutputInCommitment>, Vec<Script>), ()> {
658-
let (obscured_commitment_transaction_number, txins) = self.build_inputs(channel_static_info);
683+
let (obscured_commitment_transaction_number, txins) = self.build_inputs(holder, channel_static_info);
659684

660-
let mut txouts = self.build_outputs(channel_static_info, secp_ctx)?;
685+
let mut txouts = self.build_outputs(holder, channel_static_info, secp_ctx)?;
661686

662687
let mut outputs = Vec::with_capacity(txouts.len());
663688
let mut scripts = Vec::with_capacity(txouts.len());
@@ -683,9 +708,10 @@ impl CommitmentTransactionInfo {
683708
))
684709
}
685710

686-
fn build_outputs<T: secp256k1::Signing + secp256k1::Verification>(&self, channel_static_info: &ChannelStaticInfo, secp_ctx: &Secp256k1<T>) -> Result<Vec<(TxOut, (Script, Option<HTLCOutputInCommitment>))>, ()> {
711+
fn build_outputs<T: secp256k1::Signing + secp256k1::Verification>(&self, holder: bool, channel_static_info: &ChannelStaticInfo, secp_ctx: &Secp256k1<T>) -> Result<Vec<(TxOut, (Script, Option<HTLCOutputInCommitment>))>, ()> {
687712
let htlcs = self.htlcs.iter().map(|h| (h.clone(), ())).collect();
688-
let mut txouts = Self::do_build_outputs(&self.keys, self.to_broadcaster_value_sat, self.to_countersignatory_value_sat, &htlcs, &channel_static_info.broadcaster_pubkeys, &channel_static_info.countersignatory_pubkeys, channel_static_info.contest_delay, secp_ctx)?;
713+
let (broadcaster_pubkeys, countersignatory_pubkeys) = channel_static_info.pubkeys(holder);
714+
let mut txouts = Self::do_build_outputs(&self.keys, self.to_broadcaster_value_sat, self.to_countersignatory_value_sat, &htlcs, broadcaster_pubkeys, countersignatory_pubkeys, channel_static_info.contest_delay(holder), secp_ctx)?;
689715
let outs = txouts.drain(..).map(|(out, (s, extra))| (out, (s, extra.map(|(p, _)| p)))).collect();
690716
Ok(outs)
691717
}
@@ -760,11 +786,12 @@ impl CommitmentTransactionInfo {
760786
Ok(txouts)
761787
}
762788

763-
fn build_inputs(&self, channel_statc_info: &ChannelStaticInfo) -> (u64, Vec<TxIn>) {
789+
fn build_inputs(&self, holder: bool, channel_static_info: &ChannelStaticInfo) -> (u64, Vec<TxIn>) {
790+
let (broadcaster_pubkeys, countersignatory_pubkeys) = channel_static_info.pubkeys(holder);
764791
let commitment_transaction_number_obscure_factor = get_commitment_transaction_number_obscure_factor(
765-
&channel_statc_info.broadcaster_pubkeys.payment_point,
766-
&channel_statc_info.countersignatory_pubkeys.payment_point,
767-
channel_statc_info.is_outbound,
792+
&broadcaster_pubkeys.payment_point,
793+
&countersignatory_pubkeys.payment_point,
794+
channel_static_info.is_outbound(holder),
768795
);
769796

770797
let obscured_commitment_transaction_number =
@@ -773,7 +800,7 @@ impl CommitmentTransactionInfo {
773800
let txins = {
774801
let mut ins: Vec<TxIn> = Vec::new();
775802
ins.push(TxIn {
776-
previous_output: channel_statc_info.funding_outpoint.clone(),
803+
previous_output: channel_static_info.funding_outpoint.clone(),
777804
script_sig: Script::new(),
778805
sequence: ((0x80 as u32) << 8 * 3)
779806
| ((obscured_commitment_transaction_number >> 3 * 8) as u32),
@@ -786,26 +813,25 @@ impl CommitmentTransactionInfo {
786813

787814
/// Sign a transaction, either because we are counter-signing the counterparty's transaction or
788815
/// because we are about to broadcast a holder transaction.
789-
///
790-
/// is_outbound is true if the channel is outbound from the point of view of the broadcaster
791-
pub fn get_signature<T: secp256k1::Signing + secp256k1::Verification>(&self, channel_static_info: &ChannelStaticInfo, funding_key: &SecretKey, funding_redeemscript: &Script, channel_value_satoshis: u64, secp_ctx: &Secp256k1<T>) -> Signature {
792-
let sighash = self.get_sighash(channel_static_info, funding_redeemscript, channel_value_satoshis, secp_ctx).0;
816+
pub fn get_signature<T: secp256k1::Signing + secp256k1::Verification>(&self, holder: bool, channel_static_info: &ChannelStaticInfo, funding_key: &SecretKey, funding_redeemscript: &Script, channel_value_satoshis: u64, secp_ctx: &Secp256k1<T>) -> Signature {
817+
let sighash = self.get_sighash(holder, channel_static_info, funding_redeemscript, channel_value_satoshis, secp_ctx).0;
793818
secp_ctx.sign(&sighash, funding_key)
794819
}
795820

796821
/// Get the sighash and the transaction.
797822
///
798823
/// Builds the transaction and computes the sighash. This can be used to verify a signature.
799-
pub fn get_sighash<T: secp256k1::Signing + secp256k1::Verification>(&self, channel_static_info: &ChannelStaticInfo, funding_redeemscript: &Script, channel_value_satoshis: u64, secp_ctx: &Secp256k1<T>) -> (Message, Transaction) {
800-
let (unsigned_tx, _, _) = self.build(channel_static_info, secp_ctx).unwrap();
824+
pub fn get_sighash<T: secp256k1::Signing + secp256k1::Verification>(&self, holder: bool, channel_static_info: &ChannelStaticInfo, funding_redeemscript: &Script, channel_value_satoshis: u64, secp_ctx: &Secp256k1<T>) -> (Message, Transaction) {
825+
let (unsigned_tx, _, _) = self.build(holder, channel_static_info, secp_ctx).unwrap();
801826
let sighash = hash_to_message!(&bip143::SigHashCache::new(&unsigned_tx)
802827
.signature_hash(0, funding_redeemscript, channel_value_satoshis, SigHashType::All)[..]);
803828
(sighash, unsigned_tx)
804829
}
805830

806-
pub(crate) fn to_holder_commitment_tx<T: secp256k1::Signing + secp256k1::Verification>(&self, counterparty_sig: Signature, htlcs_with_sig: Vec<(HTLCOutputInCommitment, Option<Signature>)>, channel_static_info: &ChannelStaticInfo, secp_ctx: &Secp256k1<T>) -> HolderCommitmentTransaction {
807-
let (tx, _, _) = self.build(channel_static_info, secp_ctx).unwrap();
808-
HolderCommitmentTransaction::new_missing_holder_sig(tx, counterparty_sig, &channel_static_info.broadcaster_pubkeys.funding_pubkey, &channel_static_info.countersignatory_pubkeys.funding_pubkey, self.keys.clone(), self.feerate_per_kw, htlcs_with_sig)
831+
pub(crate) fn to_holder_commitment_tx<T: secp256k1::Signing + secp256k1::Verification>(&self, holder: bool, counterparty_sig: Signature, htlcs_with_sig: Vec<(HTLCOutputInCommitment, Option<Signature>)>, channel_static_info: &ChannelStaticInfo, secp_ctx: &Secp256k1<T>) -> HolderCommitmentTransaction {
832+
let (broadcaster_pubkeys, countersignatory_pubkeys) = channel_static_info.pubkeys(holder);
833+
let (tx, _, _) = self.build(holder, channel_static_info, secp_ctx).unwrap();
834+
HolderCommitmentTransaction::new_missing_holder_sig(tx, counterparty_sig, &broadcaster_pubkeys.funding_pubkey, &countersignatory_pubkeys.funding_pubkey, self.keys.clone(), self.feerate_per_kw, htlcs_with_sig)
809835
}
810836
}
811837

lightning/src/ln/channel.rs

Lines changed: 21 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1461,18 +1461,17 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
14611461

14621462
let keys = self.build_holder_transaction_keys(self.cur_holder_commitment_transaction_number)?;
14631463
let initial_commitment_info = self.build_commitment_transaction(self.cur_holder_commitment_transaction_number, &keys, true, false, self.feerate_per_kw, logger);
1464-
let channel_static_info = self.get_holder_channel_static_info();
1465-
let (sighash, initial_commitment_tx) = initial_commitment_info.0.get_sighash(&channel_static_info, &funding_script, self.channel_value_satoshis, &self.secp_ctx);
1464+
let channel_static_info = self.get_channel_static_info();
1465+
let (sighash, initial_commitment_tx) = initial_commitment_info.0.get_sighash(true, &channel_static_info, &funding_script, self.channel_value_satoshis, &self.secp_ctx);
14661466

14671467
// They sign the "our" commitment transaction...
14681468
log_trace!(logger, "Checking funding_created tx signature {} by key {} against tx {} (sighash {}) with redeemscript {}", log_bytes!(sig.serialize_compact()[..]), log_bytes!(self.counterparty_funding_pubkey().serialize()), encode::serialize_hex(&initial_commitment_tx), log_bytes!(sighash[..]), encode::serialize_hex(&funding_script));
14691469
secp_check!(self.secp_ctx.verify(&sighash, &sig, self.counterparty_funding_pubkey()), "Invalid funding_created signature from peer".to_owned());
14701470

14711471
let counterparty_keys = self.build_remote_transaction_keys()?;
14721472
let counterparty_initial_commitment_info = self.build_commitment_transaction(self.cur_counterparty_commitment_transaction_number, &counterparty_keys, false, false, self.feerate_per_kw, logger);
1473-
let counterparty_channel_static_info = self.get_counterparty_channel_static_info();
14741473

1475-
let counterparty_initial_commitment_tx = counterparty_initial_commitment_info.0.build(&counterparty_channel_static_info, &self.secp_ctx).unwrap().0;
1474+
let counterparty_initial_commitment_tx = counterparty_initial_commitment_info.0.build(false, &channel_static_info, &self.secp_ctx).unwrap().0;
14761475
let pre_remote_keys = PreCalculatedTxCreationKeys::new(counterparty_keys);
14771476
let counterparty_signature = self.holder_keys.sign_counterparty_commitment(self.feerate_per_kw, &counterparty_initial_commitment_tx, &pre_remote_keys, &Vec::new(), &self.secp_ctx)
14781477
.map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed".to_owned()))?.0;
@@ -1481,23 +1480,14 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
14811480
Ok((counterparty_initial_commitment_tx, initial_commitment_info.0, counterparty_signature))
14821481
}
14831482

1484-
fn get_holder_channel_static_info(&self) -> ChannelStaticInfo {
1483+
fn get_channel_static_info(&self) -> ChannelStaticInfo {
14851484
ChannelStaticInfo {
1486-
broadcaster_pubkeys: self.holder_keys.pubkeys().clone(),
1487-
countersignatory_pubkeys: self.counterparty_pubkeys.as_ref().unwrap().clone(),
1485+
holder_pubkeys: self.holder_keys.pubkeys().clone(),
1486+
counterparty_pubkeys: self.counterparty_pubkeys.as_ref().unwrap().clone(),
14881487
funding_outpoint: self.funding_txo.unwrap().into_bitcoin_outpoint(),
1489-
contest_delay: self.counterparty_selected_contest_delay,
1490-
is_outbound: self.is_outbound()
1491-
}
1492-
}
1493-
1494-
fn get_counterparty_channel_static_info(&self) -> ChannelStaticInfo {
1495-
ChannelStaticInfo {
1496-
broadcaster_pubkeys: self.counterparty_pubkeys.as_ref().unwrap().clone(),
1497-
countersignatory_pubkeys: self.holder_keys.pubkeys().clone(),
1498-
funding_outpoint: self.funding_txo.unwrap().into_bitcoin_outpoint(),
1499-
contest_delay: self.holder_selected_contest_delay,
1500-
is_outbound: !self.is_outbound()
1488+
holder_selected_contest_delay: self.holder_selected_contest_delay,
1489+
counterparty_selected_contest_delay: self.counterparty_selected_contest_delay,
1490+
is_outbound_from_holder: self.is_outbound()
15011491
}
15021492
}
15031493

@@ -1538,7 +1528,7 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
15381528
htlcs_with_sig: Vec::new(),
15391529
};
15401530

1541-
let channel_static_info = self.get_holder_channel_static_info();
1531+
let channel_static_info = self.get_channel_static_info();
15421532

15431533
let initial_commitment_tx = holder_info.to_holder_commitment_tx(&channel_static_info, &self.secp_ctx);
15441534

@@ -1586,18 +1576,17 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
15861576

15871577
let funding_script = self.get_funding_redeemscript();
15881578

1589-
let counterparty_channel_static_info = self.get_counterparty_channel_static_info();
1579+
let channel_static_info = self.get_channel_static_info();
15901580
let counterparty_keys = self.build_remote_transaction_keys()?;
15911581
let counterparty_initial_commitment_info = self.build_commitment_transaction(self.cur_counterparty_commitment_transaction_number, &counterparty_keys, false, false, self.feerate_per_kw, logger).0;
15921582
// TODO this is not integration tested
1593-
let counterparty_initial_commitment_tx = counterparty_initial_commitment_info.build(&counterparty_channel_static_info, &self.secp_ctx).unwrap().0;
1583+
let counterparty_initial_commitment_tx = counterparty_initial_commitment_info.build(false, &channel_static_info, &self.secp_ctx).unwrap().0;
15941584

15951585
// TODO this works around rustc 1.34.1 borrow issue
15961586
let channel_monitor = {
15971587
let holder_keys = self.build_holder_transaction_keys(self.cur_holder_commitment_transaction_number)?;
15981588
let initial_commitment_info = self.build_commitment_transaction(self.cur_holder_commitment_transaction_number, &holder_keys, true, false, self.feerate_per_kw, logger);
1599-
let channel_static_info = self.get_holder_channel_static_info();
1600-
let (sighash, initial_commitment_tx) = initial_commitment_info.0.get_sighash(&channel_static_info, &funding_script, self.channel_value_satoshis, &self.secp_ctx);
1589+
let (sighash, initial_commitment_tx) = initial_commitment_info.0.get_sighash(true, &channel_static_info, &funding_script, self.channel_value_satoshis, &self.secp_ctx);
16011590

16021591
let counterparty_funding_pubkey = &self.counterparty_pubkeys.as_ref().unwrap().funding_pubkey;
16031592

@@ -1987,11 +1976,11 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
19871976
self.feerate_per_kw
19881977
};
19891978

1990-
let channel_static_info = self.get_holder_channel_static_info();
1979+
let channel_static_info = self.get_channel_static_info();
19911980

19921981
let mut commitment_tx = {
19931982
let commitment_info = self.build_commitment_transaction(self.cur_holder_commitment_transaction_number, &keys, true, false, feerate_per_kw, logger);
1994-
let commitment_tx = commitment_info.0.build(&channel_static_info, &self.secp_ctx).unwrap().0;
1983+
let commitment_tx = commitment_info.0.build(true, &channel_static_info, &self.secp_ctx).unwrap().0;
19951984

19961985
let htlcs_cloned: Vec<_> = commitment_info.2.iter().map(|htlc| (htlc.0.clone(), htlc.1.map(|h| h.clone()))).collect();
19971986
(commitment_tx, commitment_info.1, htlcs_cloned)
@@ -3543,8 +3532,8 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
35433532
fn get_outbound_funding_created_signature<L: Deref>(&mut self, logger: &L) -> Result<Signature, ChannelError> where L::Target: Logger {
35443533
let counterparty_keys = self.build_remote_transaction_keys()?;
35453534
let counterparty_initial_commitment_info = self.build_commitment_transaction(self.cur_counterparty_commitment_transaction_number, &counterparty_keys, false, false, self.feerate_per_kw, logger).0;
3546-
let counterparty_channel_static_info = self.get_counterparty_channel_static_info();
3547-
let counterparty_initial_commitment_tx = counterparty_initial_commitment_info.build(&counterparty_channel_static_info, &self.secp_ctx).unwrap().0;
3535+
let channel_static_info = self.get_channel_static_info();
3536+
let counterparty_initial_commitment_tx = counterparty_initial_commitment_info.build(false, &channel_static_info, &self.secp_ctx).unwrap().0;
35483537
let pre_remote_keys = PreCalculatedTxCreationKeys::new(counterparty_keys);
35493538
Ok(self.holder_keys.sign_counterparty_commitment(self.feerate_per_kw, &counterparty_initial_commitment_tx, &pre_remote_keys, &Vec::new(), &self.secp_ctx)
35503539
.map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed".to_owned()))?.0)
@@ -3890,8 +3879,8 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
38903879

38913880
let counterparty_keys = self.build_remote_transaction_keys()?;
38923881
let counterparty_commitment_info = self.build_commitment_transaction(self.cur_counterparty_commitment_transaction_number, &counterparty_keys, false, true, feerate_per_kw, logger);
3893-
let counterparty_channel_static_info = self.get_counterparty_channel_static_info();
3894-
let counterparty_commitment_tx = counterparty_commitment_info.0.build(&counterparty_channel_static_info, &self.secp_ctx).unwrap().0;
3882+
let channel_static_info = self.get_channel_static_info();
3883+
let counterparty_commitment_tx = counterparty_commitment_info.0.build(false, &channel_static_info, &self.secp_ctx).unwrap().0;
38953884
let (signature, htlc_signatures);
38963885

38973886
{
@@ -4714,8 +4703,8 @@ mod tests {
47144703
} ) => { {
47154704
unsigned_tx = {
47164705
let mut res = chan.build_commitment_transaction(0xffffffffffff - 42, &keys, true, false, chan.feerate_per_kw, &logger);
4717-
let holder_channel_static_info = chan.get_holder_channel_static_info();
4718-
let tx = res.0.build(&holder_channel_static_info, &chan.secp_ctx).unwrap().0;
4706+
let channel_static_info = chan.get_channel_static_info();
4707+
let tx = res.0.build(true, &channel_static_info, &chan.secp_ctx).unwrap().0;
47194708

47204709
let htlcs = res.2.drain(..)
47214710
.filter_map(|(htlc, _)| if htlc.transaction_output_index.is_some() { Some(htlc) } else { None })

0 commit comments

Comments
 (0)