X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fevents%2Fbump_transaction.rs;h=dbe539505d6ca733f53a44e4ae0f515523373395;hb=19de4353d52bca8021ba3e1b8f4b036d5f5a8648;hp=5ea9bdb8e292fa4e4a6d1756a5d6c1a4df782e03;hpb=690ad18b22fbc1917b77ae5ef820a9a7fd967020;p=rust-lightning diff --git a/lightning/src/events/bump_transaction.rs b/lightning/src/events/bump_transaction.rs index 5ea9bdb8..dbe53950 100644 --- a/lightning/src/events/bump_transaction.rs +++ b/lightning/src/events/bump_transaction.rs @@ -12,12 +12,12 @@ //! [`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(&self, signer_provider: &SP) -> ::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(&self, secp: &Secp256k1) -> 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 { 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 {