Move feerate helpers to chain module
[rust-lightning] / lightning / src / events / bump_transaction.rs
index 5ea9bdb8e292fa4e4a6d1756a5d6c1a4df782e03..dbe539505d6ca733f53a44e4ae0f515523373395 100644 (file)
 //! [`Event`]: crate::events::Event
 
 use alloc::collections::BTreeMap;
-use core::convert::TryInto;
 use core::ops::Deref;
 
-use crate::chain::chaininterface::BroadcasterInterface;
+use crate::chain::chaininterface::{BroadcasterInterface, compute_feerate_sat_per_1000_weight, fee_for_weight};
 use crate::chain::ClaimId;
 use crate::io_extras::sink;
+use crate::ln::channel::ANCHOR_OUTPUT_VALUE_SATOSHI;
 use crate::ln::chan_utils;
 use crate::ln::chan_utils::{
        ANCHOR_INPUT_WITNESS_WEIGHT, HTLC_SUCCESS_INPUT_ANCHOR_WITNESS_WEIGHT,
@@ -43,14 +43,6 @@ const BASE_INPUT_SIZE: u64 = 32 /* txid */ + 4 /* vout */ + 4 /* sequence */;
 
 const BASE_INPUT_WEIGHT: u64 = BASE_INPUT_SIZE * WITNESS_SCALE_FACTOR as u64;
 
-// TODO: Define typed abstraction over feerates to handle their conversions.
-fn compute_feerate_sat_per_1000_weight(fee_sat: u64, weight: u64) -> u32 {
-       (fee_sat * 1000 / weight).try_into().unwrap_or(u32::max_value())
-}
-const fn fee_for_weight(feerate_sat_per_1000_weight: u32, weight: u64) -> u64 {
-       ((feerate_sat_per_1000_weight as u64 * weight) + 1000 - 1) / 1000
-}
-
 /// The parameters required to derive a channel signer via [`SignerProvider`].
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct ChannelDerivationParameters {
@@ -76,6 +68,39 @@ pub struct AnchorDescriptor {
 }
 
 impl AnchorDescriptor {
+       /// Returns the UTXO to be spent by the anchor input, which can be obtained via
+       /// [`Self::unsigned_tx_input`].
+       pub fn previous_utxo(&self) -> TxOut {
+               TxOut {
+                       script_pubkey: self.witness_script().to_v0_p2wsh(),
+                       value: ANCHOR_OUTPUT_VALUE_SATOSHI,
+               }
+       }
+
+       /// Returns the unsigned transaction input spending the anchor output in the commitment
+       /// transaction.
+       pub fn unsigned_tx_input(&self) -> TxIn {
+               TxIn {
+                       previous_output: self.outpoint.clone(),
+                       script_sig: Script::new(),
+                       sequence: Sequence::ENABLE_RBF_NO_LOCKTIME,
+                       witness: Witness::new(),
+               }
+       }
+
+       /// Returns the witness script of the anchor output in the commitment transaction.
+       pub fn witness_script(&self) -> Script {
+               let channel_params = self.channel_derivation_parameters.transaction_parameters.as_holder_broadcastable();
+               chan_utils::get_anchor_redeemscript(&channel_params.broadcaster_pubkeys().funding_pubkey)
+       }
+
+       /// Returns the fully signed witness required to spend the anchor output in the commitment
+       /// transaction.
+       pub fn tx_input_witness(&self, signature: &Signature) -> Witness {
+               let channel_params = self.channel_derivation_parameters.transaction_parameters.as_holder_broadcastable();
+               chan_utils::build_anchor_input_witness(&channel_params.broadcaster_pubkeys().funding_pubkey, signature)
+       }
+
        /// Derives the channel signer required to sign the anchor input.
        pub fn derive_channel_signer<SP: Deref>(&self, signer_provider: &SP) -> <SP::Target as SignerProvider>::Signer
        where
@@ -115,6 +140,15 @@ pub struct HTLCDescriptor {
 }
 
 impl HTLCDescriptor {
+       /// Returns the UTXO to be spent by the HTLC input, which can be obtained via
+       /// [`Self::unsigned_tx_input`].
+       pub fn previous_utxo<C: secp256k1::Signing + secp256k1::Verification>(&self, secp: &Secp256k1<C>) -> TxOut {
+               TxOut {
+                       script_pubkey: self.witness_script(secp).to_v0_p2wsh(),
+                       value: self.htlc.amount_msat / 1000,
+               }
+       }
+
        /// Returns the unsigned transaction input spending the HTLC output in the commitment
        /// transaction.
        pub fn unsigned_tx_input(&self) -> TxIn {
@@ -301,6 +335,8 @@ pub enum BumpTransactionEvent {
 pub struct Input {
        /// The unique identifier of the input.
        pub outpoint: OutPoint,
+       /// The UTXO being spent by the input.
+       pub previous_utxo: TxOut,
        /// The upper-bound weight consumed by the input's full [`TxIn::script_sig`] and
        /// [`TxIn::witness`], each with their lengths included, required to satisfy the output's
        /// script.
@@ -640,6 +676,7 @@ where
        ) -> Result<Transaction, ()> {
                let must_spend = vec![Input {
                        outpoint: anchor_descriptor.outpoint,
+                       previous_utxo: anchor_descriptor.previous_utxo(),
                        satisfaction_weight: commitment_tx.weight() as u64 + ANCHOR_INPUT_WITNESS_WEIGHT + EMPTY_SCRIPT_SIG_WEIGHT,
                }];
                let coin_selection = self.utxo_source.select_confirmed_utxos(
@@ -649,12 +686,7 @@ where
                let mut tx = Transaction {
                        version: 2,
                        lock_time: PackedLockTime::ZERO, // TODO: Use next best height.
-                       input: vec![TxIn {
-                               previous_output: anchor_descriptor.outpoint,
-                               script_sig: Script::new(),
-                               sequence: Sequence::ZERO,
-                               witness: Witness::new(),
-                       }],
+                       input: vec![anchor_descriptor.unsigned_tx_input()],
                        output: vec![],
                };
                self.process_coin_selection(&mut tx, coin_selection);
@@ -688,8 +720,7 @@ where
                self.utxo_source.sign_tx(&mut anchor_tx)?;
                let signer = anchor_descriptor.derive_channel_signer(&self.signer_provider);
                let anchor_sig = signer.sign_holder_anchor_input(&anchor_tx, 0, &self.secp)?;
-               anchor_tx.input[0].witness =
-                       chan_utils::build_anchor_input_witness(&signer.pubkeys().funding_pubkey, &anchor_sig);
+               anchor_tx.input[0].witness = anchor_descriptor.tx_input_witness(&anchor_sig);
 
                self.broadcaster.broadcast_transactions(&[&commitment_tx, &anchor_tx]);
                Ok(())
@@ -712,6 +743,7 @@ where
                        let htlc_input = htlc_descriptor.unsigned_tx_input();
                        must_spend.push(Input {
                                outpoint: htlc_input.previous_output.clone(),
+                               previous_utxo: htlc_descriptor.previous_utxo(&self.secp),
                                satisfaction_weight: EMPTY_SCRIPT_SIG_WEIGHT + if htlc_descriptor.preimage.is_some() {
                                        HTLC_SUCCESS_INPUT_ANCHOR_WITNESS_WEIGHT
                                } else {