+ fn initial_counterparty_commitment_tx(&mut self) -> Option<CommitmentTransaction> {
+ let (their_per_commitment_point, feerate_per_kw, to_broadcaster_value,
+ to_countersignatory_value) = self.initial_counterparty_commitment_info?;
+ let htlc_outputs = vec![];
+
+ let commitment_tx = self.build_counterparty_commitment_tx(INITIAL_COMMITMENT_NUMBER,
+ &their_per_commitment_point, to_broadcaster_value, to_countersignatory_value,
+ feerate_per_kw, htlc_outputs);
+ Some(commitment_tx)
+ }
+
+ fn build_counterparty_commitment_tx(
+ &self, commitment_number: u64, their_per_commitment_point: &PublicKey,
+ to_broadcaster_value: u64, to_countersignatory_value: u64, feerate_per_kw: u32,
+ mut nondust_htlcs: Vec<(HTLCOutputInCommitment, Option<Box<HTLCSource>>)>
+ ) -> CommitmentTransaction {
+ let broadcaster_keys = &self.onchain_tx_handler.channel_transaction_parameters
+ .counterparty_parameters.as_ref().unwrap().pubkeys;
+ let countersignatory_keys =
+ &self.onchain_tx_handler.channel_transaction_parameters.holder_pubkeys;
+
+ let broadcaster_funding_key = broadcaster_keys.funding_pubkey;
+ let countersignatory_funding_key = countersignatory_keys.funding_pubkey;
+ let keys = TxCreationKeys::from_channel_static_keys(&their_per_commitment_point,
+ &broadcaster_keys, &countersignatory_keys, &self.onchain_tx_handler.secp_ctx);
+ let channel_parameters =
+ &self.onchain_tx_handler.channel_transaction_parameters.as_counterparty_broadcastable();
+
+ CommitmentTransaction::new_with_auxiliary_htlc_data(commitment_number,
+ to_broadcaster_value, to_countersignatory_value, broadcaster_funding_key,
+ countersignatory_funding_key, keys, feerate_per_kw, &mut nondust_htlcs,
+ channel_parameters)
+ }
+
+ fn counterparty_commitment_txs_from_update(&self, update: &ChannelMonitorUpdate) -> Vec<CommitmentTransaction> {
+ update.updates.iter().filter_map(|update| {
+ match update {
+ &ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo { commitment_txid,
+ ref htlc_outputs, commitment_number, their_per_commitment_point,
+ feerate_per_kw: Some(feerate_per_kw),
+ to_broadcaster_value_sat: Some(to_broadcaster_value),
+ to_countersignatory_value_sat: Some(to_countersignatory_value) } => {
+
+ let nondust_htlcs = htlc_outputs.iter().filter_map(|(htlc, _)| {
+ htlc.transaction_output_index.map(|_| (htlc.clone(), None))
+ }).collect::<Vec<_>>();
+
+ let commitment_tx = self.build_counterparty_commitment_tx(commitment_number,
+ &their_per_commitment_point, to_broadcaster_value,
+ to_countersignatory_value, feerate_per_kw, nondust_htlcs);
+
+ debug_assert_eq!(commitment_tx.trust().txid(), commitment_txid);
+
+ Some(commitment_tx)
+ },
+ _ => None,
+ }
+ }).collect()
+ }
+
+ fn sign_to_local_justice_tx(
+ &self, mut justice_tx: Transaction, input_idx: usize, value: u64, commitment_number: u64
+ ) -> Result<Transaction, ()> {
+ let secret = self.get_secret(commitment_number).ok_or(())?;
+ let per_commitment_key = SecretKey::from_slice(&secret).map_err(|_| ())?;
+ let their_per_commitment_point = PublicKey::from_secret_key(
+ &self.onchain_tx_handler.secp_ctx, &per_commitment_key);
+
+ let revocation_pubkey = RevocationKey::from_basepoint(&self.onchain_tx_handler.secp_ctx,
+ &self.holder_revocation_basepoint, &their_per_commitment_point);
+ let delayed_key = DelayedPaymentKey::from_basepoint(&self.onchain_tx_handler.secp_ctx,
+ &self.counterparty_commitment_params.counterparty_delayed_payment_base_key, &their_per_commitment_point);
+ let revokeable_redeemscript = chan_utils::get_revokeable_redeemscript(&revocation_pubkey,
+ self.counterparty_commitment_params.on_counterparty_tx_csv, &delayed_key);
+
+ let sig = self.onchain_tx_handler.signer.sign_justice_revoked_output(
+ &justice_tx, input_idx, value, &per_commitment_key, &self.onchain_tx_handler.secp_ctx)?;
+ justice_tx.input[input_idx].witness.push_bitcoin_signature(&sig.serialize_der(), EcdsaSighashType::All);
+ justice_tx.input[input_idx].witness.push(&[1u8]);
+ justice_tx.input[input_idx].witness.push(revokeable_redeemscript.as_bytes());
+ Ok(justice_tx)
+ }
+