Skip to content

Commit 4f1a9ff

Browse files
committed
Introduce CounterpartyChannelTransactionParameters
also, eliminate ChannelStaticData in favor of ChannelTransactionParameters
1 parent 91af0bc commit 4f1a9ff

File tree

5 files changed

+213
-211
lines changed

5 files changed

+213
-211
lines changed

lightning/src/chain/channelmonitor.rs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -960,8 +960,9 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
960960
let payment_key_hash = WPubkeyHash::hash(&keys.pubkeys().payment_point.serialize());
961961
let counterparty_payment_script = Builder::new().push_opcode(opcodes::all::OP_PUSHBYTES_0).push_slice(&payment_key_hash[..]).into_script();
962962

963-
let counterparty_delayed_payment_base_key = channel_parameters.counterparty_pubkeys.delayed_payment_basepoint;
964-
let counterparty_htlc_base_key = channel_parameters.counterparty_pubkeys.htlc_basepoint;
963+
let counterparty_channel_parameters = channel_parameters.counterparty_parameters.as_ref().unwrap();
964+
let counterparty_delayed_payment_base_key = counterparty_channel_parameters.pubkeys.delayed_payment_basepoint;
965+
let counterparty_htlc_base_key = counterparty_channel_parameters.pubkeys.htlc_basepoint;
965966
let counterparty_tx_cache = CounterpartyCommitmentTransaction { counterparty_delayed_payment_base_key, counterparty_htlc_base_key, on_counterparty_tx_csv, per_htlc: HashMap::new() };
966967

967968
let mut onchain_tx_handler = OnchainTxHandler::new(destination_script.clone(), keys.clone(), channel_parameters.clone());
@@ -1012,7 +1013,7 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
10121013
channel_value_satoshis,
10131014
their_cur_revocation_points: None,
10141015

1015-
on_holder_tx_csv: channel_parameters.counterparty_selected_contest_delay,
1016+
on_holder_tx_csv: counterparty_channel_parameters.selected_contest_delay,
10161017

10171018
commitment_secrets: CounterpartyCommitmentSecrets::new(),
10181019
counterparty_claimable_outpoints: HashMap::new(),
@@ -2605,7 +2606,7 @@ mod tests {
26052606
use ln::channelmanager::{PaymentPreimage, PaymentHash};
26062607
use ln::onchaintx::{OnchainTxHandler, InputDescriptors};
26072608
use ln::chan_utils;
2608-
use ln::chan_utils::{HTLCOutputInCommitment, ChannelPublicKeys, ChannelTransactionParameters, HolderCommitmentTransaction};
2609+
use ln::chan_utils::{HTLCOutputInCommitment, ChannelPublicKeys, ChannelTransactionParameters, HolderCommitmentTransaction, CounterpartyChannelTransactionParameters};
26092610
use util::test_utils::{TestLogger, TestBroadcaster, TestFeeEstimator};
26102611
use bitcoin::secp256k1::key::{SecretKey,PublicKey};
26112612
use bitcoin::secp256k1::Secp256k1;
@@ -2685,13 +2686,16 @@ mod tests {
26852686
delayed_payment_basepoint: PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[47; 32]).unwrap()),
26862687
htlc_basepoint: PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[48; 32]).unwrap())
26872688
};
2689+
let funding_outpoint = OutPoint { txid: Default::default(), index: u16::max_value() };
26882690
let channel_parameters = ChannelTransactionParameters {
26892691
holder_pubkeys: keys.holder_channel_pubkeys.clone(),
2690-
counterparty_pubkeys,
26912692
holder_selected_contest_delay: 66,
2692-
counterparty_selected_contest_delay: 67,
2693-
funding_outpoint: Default::default(),
2694-
is_outbound_from_holder: true
2693+
is_outbound_from_holder: true,
2694+
counterparty_parameters: Some(CounterpartyChannelTransactionParameters {
2695+
pubkeys: counterparty_pubkeys,
2696+
selected_contest_delay: 67,
2697+
}),
2698+
funding_outpoint: Some(funding_outpoint),
26952699
};
26962700
// Prune with one old state and a holder commitment tx holding a few overlaps with the
26972701
// old state.

lightning/src/chain/keysinterface.rs

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

3434
use chain::transaction::OutPoint;
3535
use ln::chan_utils;
36-
use ln::chan_utils::{HTLCOutputInCommitment, make_funding_redeemscript, ChannelPublicKeys, HolderCommitmentTransaction, ChannelTransactionParameters, CommitmentTransaction};
36+
use ln::chan_utils::{HTLCOutputInCommitment, make_funding_redeemscript, ChannelPublicKeys, HolderCommitmentTransaction, ChannelTransactionParameters, CommitmentTransaction, CounterpartyChannelTransactionParameters};
3737
use ln::msgs::UnsignedChannelAnnouncement;
3838

3939
use std::sync::atomic::{AtomicUsize, Ordering};
@@ -327,7 +327,7 @@ pub trait ChannelKeys : Send+Clone {
327327
/// We bind holder_selected_contest_delay late here for API convenience.
328328
///
329329
/// Will be called before any signatures are applied.
330-
fn ready_channel(&mut self, channel_points: &ChannelPublicKeys, counterparty_selected_contest_delay: u16, holder_selected_contest_delay: u16, is_outbound: bool, funding_outpoint: &OutPoint);
330+
fn ready_channel(&mut self, channel_parameters: &ChannelTransactionParameters);
331331
}
332332

333333
/// A trait to describe an object which can get user secrets and key material.
@@ -389,9 +389,7 @@ pub struct InMemoryChannelKeys {
389389
/// Holder public keys and basepoints
390390
pub(crate) holder_channel_pubkeys: ChannelPublicKeys,
391391
/// Counterparty public keys and counterparty/holder selected_contest_delay, populated on channel acceptance
392-
accepted_channel_data: Option<StaticChannelData>,
393-
/// Funding outpoint, populated on channel funding creation
394-
funding_outpoint: Option<OutPoint>,
392+
channel_parameters: Option<ChannelTransactionParameters>,
395393
/// The total value of this channel
396394
channel_value_satoshis: u64,
397395
/// Key derivation parameters
@@ -423,8 +421,7 @@ impl InMemoryChannelKeys {
423421
commitment_seed,
424422
channel_value_satoshis,
425423
holder_channel_pubkeys,
426-
accepted_channel_data: None,
427-
funding_outpoint: None,
424+
channel_parameters: None,
428425
key_derivation_params,
429426
}
430427
}
@@ -447,27 +444,27 @@ impl InMemoryChannelKeys {
447444

448445
/// Counterparty pubkeys.
449446
/// Will panic if ready_channel wasn't called.
450-
pub fn counterparty_pubkeys(&self) -> &ChannelPublicKeys { &self.accepted_channel_data.as_ref().unwrap().counterparty_channel_pubkeys }
447+
pub fn counterparty_pubkeys(&self) -> &ChannelPublicKeys { &self.channel_parameters.as_ref().unwrap().counterparty_parameters.as_ref().unwrap().pubkeys }
451448

452449
/// The contest_delay value specified by our counterparty and applied on holder-broadcastable
453450
/// transactions, ie the amount of time that we have to wait to recover our funds if we
454451
/// broadcast a transaction. You'll likely want to pass this to the
455452
/// ln::chan_utils::build*_transaction functions when signing holder's transactions.
456453
/// Will panic if ready_channel wasn't called.
457-
pub fn counterparty_selected_contest_delay(&self) -> u16 { self.accepted_channel_data.as_ref().unwrap().counterparty_selected_contest_delay }
454+
pub fn counterparty_selected_contest_delay(&self) -> u16 { self.channel_parameters.as_ref().unwrap().counterparty_parameters.as_ref().unwrap().selected_contest_delay }
458455

459456
/// The contest_delay value specified by us and applied on transactions broadcastable
460457
/// by our counterparty, ie the amount of time that they have to wait to recover their funds
461458
/// if they broadcast a transaction.
462459
/// Will panic if ready_channel wasn't called.
463-
pub fn holder_selected_contest_delay(&self) -> u16 { self.accepted_channel_data.as_ref().unwrap().holder_selected_contest_delay }
460+
pub fn holder_selected_contest_delay(&self) -> u16 { self.channel_parameters.as_ref().unwrap().holder_selected_contest_delay }
464461

465462
/// Whether the holder is the initiator
466-
pub fn is_outbound(&self) -> bool { self.accepted_channel_data.as_ref().unwrap().is_outbound }
463+
pub fn is_outbound(&self) -> bool { self.channel_parameters.as_ref().unwrap().is_outbound_from_holder }
467464

468465
/// Funding outpoint
469466
/// Will panic if ready_channel wasn't called.
470-
pub fn funding_outpoint(&self) -> &OutPoint { self.funding_outpoint.as_ref().unwrap() }
467+
pub fn funding_outpoint(&self) -> &OutPoint { self.channel_parameters.as_ref().unwrap().funding_outpoint.as_ref().unwrap() }
471468
}
472469

473470
impl ChannelKeys for InMemoryChannelKeys {
@@ -487,8 +484,7 @@ impl ChannelKeys for InMemoryChannelKeys {
487484
let keys = commitment_tx.trust_key_derivation();
488485

489486
let funding_pubkey = PublicKey::from_secret_key(secp_ctx, &self.funding_key);
490-
let accepted_data = self.accepted_channel_data.as_ref().expect("must accept before signing");
491-
let channel_funding_redeemscript = make_funding_redeemscript(&funding_pubkey, &accepted_data.counterparty_channel_pubkeys.funding_pubkey);
487+
let channel_funding_redeemscript = make_funding_redeemscript(&funding_pubkey, &self.counterparty_pubkeys().funding_pubkey);
492488

493489
let channel_parameters = self.make_channel_parameters();
494490
let directed_channel_parameters = channel_parameters.to_directed(false);
@@ -498,7 +494,7 @@ impl ChannelKeys for InMemoryChannelKeys {
498494

499495
let mut htlc_sigs = Vec::with_capacity(commitment_tx.htlcs.len());
500496
for htlc in &commitment_tx.htlcs {
501-
let htlc_tx = chan_utils::build_htlc_transaction(&commitment_txid, commitment_tx.feerate_per_kw, accepted_data.holder_selected_contest_delay, htlc, &keys.broadcaster_delayed_payment_key, &keys.revocation_key);
497+
let htlc_tx = chan_utils::build_htlc_transaction(&commitment_txid, commitment_tx.feerate_per_kw, self.holder_selected_contest_delay(), htlc, &keys.broadcaster_delayed_payment_key, &keys.revocation_key);
502498
let htlc_redeemscript = chan_utils::get_htlc_redeemscript(&htlc, &keys);
503499
let htlc_sighash = hash_to_message!(&bip143::SigHashCache::new(&htlc_tx).signature_hash(0, &htlc_redeemscript, htlc.amount_msat / 1000, SigHashType::All)[..]);
504500
let our_htlc_key = match chan_utils::derive_private_key(&secp_ctx, &keys.per_commitment_point, &self.htlc_base_key) {
@@ -527,8 +523,7 @@ impl ChannelKeys for InMemoryChannelKeys {
527523
#[cfg(any(test,feature = "unsafe_revoked_tx_signing"))]
528524
fn unsafe_sign_holder_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, holder_commitment_tx: &HolderCommitmentTransaction, secp_ctx: &Secp256k1<T>) -> Result<Signature, ()> {
529525
let funding_pubkey = PublicKey::from_secret_key(secp_ctx, &self.funding_key);
530-
let counterparty_channel_pubkeys = &self.accepted_channel_data.as_ref().expect("must accept before signing").counterparty_channel_pubkeys;
531-
let channel_funding_redeemscript = make_funding_redeemscript(&funding_pubkey, &counterparty_channel_pubkeys.funding_pubkey);
526+
let channel_funding_redeemscript = make_funding_redeemscript(&funding_pubkey, &self.counterparty_pubkeys().funding_pubkey);
532527
let channel_parameters = self.make_channel_parameters();
533528
let channel_parameters = channel_parameters.to_directed(true);
534529

@@ -595,8 +590,7 @@ impl ChannelKeys for InMemoryChannelKeys {
595590
if closing_tx.output.len() > 2 { return Err(()); }
596591

597592
let funding_pubkey = PublicKey::from_secret_key(secp_ctx, &self.funding_key);
598-
let counterparty_channel_data = self.accepted_channel_data.as_ref().expect("must accept before signing");
599-
let channel_funding_redeemscript = make_funding_redeemscript(&funding_pubkey, &counterparty_channel_data.counterparty_channel_pubkeys.funding_pubkey);
593+
let channel_funding_redeemscript = make_funding_redeemscript(&funding_pubkey, &self.counterparty_pubkeys().funding_pubkey);
600594

601595
let sighash = hash_to_message!(&bip143::SigHashCache::new(closing_tx)
602596
.signature_hash(0, &channel_funding_redeemscript, self.channel_value_satoshis, SigHashType::All)[..]);
@@ -608,23 +602,13 @@ impl ChannelKeys for InMemoryChannelKeys {
608602
Ok(secp_ctx.sign(&msghash, &self.funding_key))
609603
}
610604

611-
fn ready_channel(&mut self, channel_pubkeys: &ChannelPublicKeys, counterparty_selected_contest_delay: u16, holder_selected_contest_delay: u16, is_outbound: bool, funding_outpoint: &OutPoint) {
612-
assert!(self.accepted_channel_data.is_none(), "Acceptance already noted");
613-
self.accepted_channel_data = Some(StaticChannelData {
614-
counterparty_channel_pubkeys: channel_pubkeys.clone(),
615-
counterparty_selected_contest_delay,
616-
holder_selected_contest_delay,
617-
is_outbound,
618-
});
619-
assert!(self.funding_outpoint.is_none(), "Funding creation already noted");
620-
self.funding_outpoint = Some(funding_outpoint.clone());
605+
fn ready_channel(&mut self, channel_parameters: &ChannelTransactionParameters) {
606+
assert!(self.channel_parameters.is_none(), "Acceptance already noted");
607+
assert!(channel_parameters.is_populated(), "Channel parameters must be fully populated");
608+
self.channel_parameters = Some(channel_parameters.clone());
621609
}
622610
}
623611

624-
625-
impl_writeable!(StaticChannelData, 0,
626-
{ counterparty_channel_pubkeys, counterparty_selected_contest_delay, holder_selected_contest_delay, is_outbound });
627-
628612
impl Writeable for InMemoryChannelKeys {
629613
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), Error> {
630614
self.funding_key.write(writer)?;
@@ -633,8 +617,7 @@ impl Writeable for InMemoryChannelKeys {
633617
self.delayed_payment_base_key.write(writer)?;
634618
self.htlc_base_key.write(writer)?;
635619
self.commitment_seed.write(writer)?;
636-
self.accepted_channel_data.write(writer)?;
637-
self.funding_outpoint.write(writer)?;
620+
self.channel_parameters.write(writer)?;
638621
self.channel_value_satoshis.write(writer)?;
639622
self.key_derivation_params.0.write(writer)?;
640623
self.key_derivation_params.1.write(writer)?;
@@ -652,7 +635,6 @@ impl Readable for InMemoryChannelKeys {
652635
let htlc_base_key = Readable::read(reader)?;
653636
let commitment_seed = Readable::read(reader)?;
654637
let counterparty_channel_data = Readable::read(reader)?;
655-
let funding_outpoint = Readable::read(reader)?;
656638
let channel_value_satoshis = Readable::read(reader)?;
657639
let secp_ctx = Secp256k1::signing_only();
658640
let holder_channel_pubkeys =
@@ -671,8 +653,7 @@ impl Readable for InMemoryChannelKeys {
671653
commitment_seed,
672654
channel_value_satoshis,
673655
holder_channel_pubkeys,
674-
accepted_channel_data: counterparty_channel_data,
675-
funding_outpoint,
656+
channel_parameters: counterparty_channel_data,
676657
key_derivation_params: (params_1, params_2),
677658
})
678659
}
@@ -858,11 +839,13 @@ impl InMemoryChannelKeys {
858839
pub(crate) fn make_channel_parameters(&self) -> ChannelTransactionParameters {
859840
ChannelTransactionParameters {
860841
holder_pubkeys: self.pubkeys().clone(),
861-
counterparty_pubkeys: self.counterparty_pubkeys().clone(),
862842
holder_selected_contest_delay: self.holder_selected_contest_delay(),
863-
counterparty_selected_contest_delay: self.counterparty_selected_contest_delay(),
864-
funding_outpoint: self.funding_outpoint().into_bitcoin_outpoint(),
865-
is_outbound_from_holder: self.is_outbound()
843+
is_outbound_from_holder: self.is_outbound(),
844+
counterparty_parameters: Some(CounterpartyChannelTransactionParameters {
845+
pubkeys: self.counterparty_pubkeys().clone(),
846+
selected_contest_delay: self.counterparty_selected_contest_delay(),
847+
}),
848+
funding_outpoint: Some(self.funding_outpoint().clone()),
866849
}
867850
}
868851
}

lightning/src/ln/chan_utils.rs

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ use ln::chan_utils;
3737
use util::transaction_utils::sort_outputs;
3838
use ln::channel::INITIAL_COMMITMENT_NUMBER;
3939
use std::io::Read;
40+
use chain;
4041

4142
const HTLC_OUTPUT_IN_COMMITMENT_SIZE: usize = 1 + 8 + 4 + 32 + 5;
4243

@@ -543,6 +544,17 @@ pub fn build_htlc_transaction(prev_hash: &Txid, feerate_per_kw: u32, contest_del
543544
}
544545
}
545546

547+
/// Late-bound per-channel data used to build transactions.
548+
///
549+
/// This is a sub-structure of ChannelTransactionParameters.
550+
#[derive(Clone)]
551+
pub struct CounterpartyChannelTransactionParameters {
552+
/// Counter-party public keys
553+
pub pubkeys: ChannelPublicKeys,
554+
/// The contest delay selected by the counterparty, which applies to holder-broadcast transactions
555+
pub selected_contest_delay: u16,
556+
}
557+
546558
/// Per-channel data used to build transactions in conjunction with the per-commitment data (CommitmentTransaction).
547559
///
548560
/// Normally, this is converted to the owner-independent DirectedChannelTransactionParameters
@@ -551,36 +563,47 @@ pub fn build_htlc_transaction(prev_hash: &Txid, feerate_per_kw: u32, contest_del
551563
pub struct ChannelTransactionParameters {
552564
/// Holder public keys
553565
pub holder_pubkeys: ChannelPublicKeys,
554-
/// Counter-party public keys
555-
pub counterparty_pubkeys: ChannelPublicKeys,
556566
/// The contest delay selected by the holder, which applies to counterparty-broadcast transactions
557567
pub holder_selected_contest_delay: u16,
558-
/// The contest delay selected by the counterparty, which applies to holder-broadcast transactions
559-
pub counterparty_selected_contest_delay: u16,
560-
/// The funding outpoint
561-
pub funding_outpoint: OutPoint,
562568
/// Whether the holder is the initiator of this channel.
563569
/// This is an input to the commitment number obscure factor computation.
564570
pub is_outbound_from_holder: bool,
571+
/// The late-bound counterparty channel transaction parameters.
572+
/// These parameters are populated at the point in the protocol where the counterparty provides them.
573+
pub counterparty_parameters: Option<CounterpartyChannelTransactionParameters>,
574+
/// The late-bound funding outpoint
575+
pub funding_outpoint: Option<chain::transaction::OutPoint>,
565576
}
566577

567578
impl ChannelTransactionParameters {
568-
/// Convert the owner specific parameters to owner independent parameters
579+
/// Whether the late bound parameters are populated.
580+
pub fn is_populated(&self) -> bool {
581+
self.counterparty_parameters.is_some() && self.funding_outpoint.is_some()
582+
}
583+
584+
/// Convert the owner specific parameters to owner independent parameters.
585+
///
586+
/// self.is_populated() must be true before calling this function.
569587
pub fn to_directed(&self, broadcaster_is_holder: bool) -> DirectedChannelTransactionParameters {
588+
assert!(self.is_populated(), "self.late_parameters must be set before using to_directed");
570589
DirectedChannelTransactionParameters {
571590
inner: self,
572591
broadcaster_is_holder
573592
}
574593
}
575594
}
576595

596+
impl_writeable!(CounterpartyChannelTransactionParameters, 0, {
597+
pubkeys,
598+
selected_contest_delay
599+
});
600+
577601
impl_writeable!(ChannelTransactionParameters, 0, {
578602
holder_pubkeys,
579-
counterparty_pubkeys,
580603
holder_selected_contest_delay,
581-
counterparty_selected_contest_delay,
582-
funding_outpoint,
583-
is_outbound_from_holder
604+
is_outbound_from_holder,
605+
counterparty_parameters,
606+
funding_outpoint
584607
});
585608

586609
/// Static channel fields used to build transactions given per-commitment fields (CommitmentTransaction).
@@ -602,30 +625,32 @@ pub struct DirectedChannelTransactionParameters<'a> {
602625
impl<'a> DirectedChannelTransactionParameters<'a> {
603626
/// Get the pubkeys for the broadcaster and countersignatory
604627
pub fn pubkeys(&self) -> (&ChannelPublicKeys, &ChannelPublicKeys) {
628+
let counterparty_parameters = self.inner.counterparty_parameters.as_ref().unwrap();
605629
if self.broadcaster_is_holder {
606-
(&self.inner.holder_pubkeys, &self.inner.counterparty_pubkeys)
630+
(&self.inner.holder_pubkeys, &counterparty_parameters.pubkeys)
607631
} else {
608-
(&self.inner.counterparty_pubkeys, &self.inner.holder_pubkeys)
632+
(&counterparty_parameters.pubkeys, &self.inner.holder_pubkeys)
609633
}
610634
}
611635

612636
/// Get the contest delay applicable to the transactions.
613637
/// Note that the contest delay was selected by the countersignatory.
614638
pub fn contest_delay(&self) -> u16 {
615-
if self.broadcaster_is_holder { self.inner.counterparty_selected_contest_delay } else { self.inner.holder_selected_contest_delay }
639+
let counterparty_parameters = self.inner.counterparty_parameters.as_ref().unwrap();
640+
if self.broadcaster_is_holder { counterparty_parameters.selected_contest_delay } else { self.inner.holder_selected_contest_delay }
616641
}
617642

618643
/// Whether the channel is outbound from the broadcaster.
619644
///
620645
/// The boolean representing the side that initiated the channel is
621646
/// an input to the commitment number obscure factor computation.
622647
pub fn is_outbound(&self) -> bool {
623-
return if self.broadcaster_is_holder { self.inner.is_outbound_from_holder } else { !self.inner.is_outbound_from_holder };
648+
if self.broadcaster_is_holder { self.inner.is_outbound_from_holder } else { !self.inner.is_outbound_from_holder }
624649
}
625650

626651
/// The funding outpoint
627652
pub fn funding_outpoint(&self) -> OutPoint {
628-
self.inner.funding_outpoint
653+
self.inner.funding_outpoint.unwrap().into_bitcoin_outpoint()
629654
}
630655
}
631656

@@ -642,7 +667,7 @@ pub struct HolderCommitmentTransaction {
642667
/// All non-dust counterparty HTLC signatures, in the order they appear in the transaction
643668
pub counterparty_htlc_sigs: Vec<Signature>,
644669
// Which order the signatures should go in when constructing the final commitment tx witness.
645-
// The user should be able to reconstruc this themselves, so we don't bother to expose it.
670+
// The user should be able to reconstruct this themselves, so we don't bother to expose it.
646671
holder_sig_first: bool,
647672
}
648673

0 commit comments

Comments
 (0)