diff --git a/lightning/src/chain/channelmonitor.rs b/lightning/src/chain/channelmonitor.rs index 62d254a5377..9b72872b3ce 100644 --- a/lightning/src/chain/channelmonitor.rs +++ b/lightning/src/chain/channelmonitor.rs @@ -4095,6 +4095,7 @@ impl ChannelMonitorImpl { revocation_pubkey: broadcasted_holder_revokable_script.2, channel_keys_id: self.channel_keys_id, channel_value_satoshis: self.channel_value_satoshis, + delayed_payment_basepoint: self.onchain_tx_handler.signer.pubkeys().delayed_payment_basepoint, })); } } diff --git a/lightning/src/sign/mod.rs b/lightning/src/sign/mod.rs index 73a80615c58..41e7232b423 100644 --- a/lightning/src/sign/mod.rs +++ b/lightning/src/sign/mod.rs @@ -103,7 +103,10 @@ pub struct DelayedPaymentOutputDescriptor { pub channel_keys_id: [u8; 32], /// The value of the channel which this output originated from, possibly indirectly. pub channel_value_satoshis: u64, + /// Channel base key used to generate a witness data to spend this output. + pub delayed_payment_basepoint: DelayedPaymentBasepoint } + impl DelayedPaymentOutputDescriptor { /// The maximum length a well-formed witness spending one of these should have. /// Note: If you have the grind_signatures feature enabled, this will be at least 1 byte @@ -121,6 +124,7 @@ impl_writeable_tlv_based!(DelayedPaymentOutputDescriptor, { (8, revocation_pubkey, required), (10, channel_keys_id, required), (12, channel_value_satoshis, required), + (14, delayed_payment_basepoint, required), }); pub(crate) const P2WPKH_WITNESS_WEIGHT: u64 = 1 /* num stack items */ + @@ -305,7 +309,7 @@ impl SpendableOutputDescriptor { /// /// This is not exported to bindings users as there is no standard serialization for an input. /// See [`Self::create_spendable_outputs_psbt`] instead. - pub fn to_psbt_input(&self, secp_ctx: &Secp256k1, delayed_payment_basepoint: Option<&DelayedPaymentBasepoint>) -> bitcoin::psbt::Input { + pub fn to_psbt_input(&self, secp_ctx: &Secp256k1) -> bitcoin::psbt::Input { match self { SpendableOutputDescriptor::StaticOutput { output, .. } => { // Is a standard P2WPKH, no need for witness script @@ -315,10 +319,10 @@ impl SpendableOutputDescriptor { } }, SpendableOutputDescriptor::DelayedPaymentOutput(descriptor) => { - let witness_script = delayed_payment_basepoint.map(|basepoint| { + let witness_script = { let payment_key = DelayedPaymentKey::from_basepoint( secp_ctx, - basepoint, + &descriptor.delayed_payment_basepoint, &descriptor.per_commitment_point, ); get_revokeable_redeemscript( @@ -326,10 +330,10 @@ impl SpendableOutputDescriptor { descriptor.to_self_delay, &payment_key, ) - }); + }; bitcoin::psbt::Input { witness_utxo: Some(descriptor.output.clone()), - witness_script: witness_script, + witness_script: Some(witness_script), ..Default::default() } }, @@ -359,7 +363,7 @@ impl SpendableOutputDescriptor { /// does not match the one we can spend. /// /// We do not enforce that outputs meet the dust limit or that any output scripts are standard. - pub fn create_spendable_outputs_psbt(descriptors: &[&SpendableOutputDescriptor], outputs: Vec, change_destination_script: ScriptBuf, feerate_sat_per_1000_weight: u32, locktime: Option, delayed_payment_basepoint: Option<&DelayedPaymentBasepoint>) -> Result<(PartiallySignedTransaction, u64), ()> { + pub fn create_spendable_outputs_psbt(descriptors: &[&SpendableOutputDescriptor], outputs: Vec, change_destination_script: ScriptBuf, feerate_sat_per_1000_weight: u32, locktime: Option) -> Result<(PartiallySignedTransaction, u64), ()> { let secp_ctx = Secp256k1::new(); let mut input = Vec::with_capacity(descriptors.len()); let mut input_value = 0; @@ -404,7 +408,7 @@ impl SpendableOutputDescriptor { { witness_weight -= 1; } // Guarantees a low R signature input_value += descriptor.output.value; - add_tweak = delayed_payment_basepoint.and_then(|basepoint| Some(derive_add_tweak(&descriptor.per_commitment_point, &basepoint))); + add_tweak = Some(derive_add_tweak(&descriptor.per_commitment_point, &descriptor.delayed_payment_basepoint)); }, SpendableOutputDescriptor::StaticOutput { ref outpoint, ref output, .. } => { if !output_set.insert(*outpoint) { return Err(()); } @@ -431,7 +435,7 @@ impl SpendableOutputDescriptor { let expected_max_weight = transaction_utils::maybe_add_change_output(&mut tx, input_value, witness_weight, feerate_sat_per_1000_weight, change_destination_script)?; - let psbt_inputs = descriptors.iter().map(|d| d.to_psbt_input(&secp_ctx, delayed_payment_basepoint)).collect::>(); + let psbt_inputs = descriptors.iter().map(|d| d.to_psbt_input(&secp_ctx)).collect::>(); let psbt = PartiallySignedTransaction { inputs: psbt_inputs, outputs: vec![Default::default(); tx.output.len()], @@ -1656,7 +1660,7 @@ impl KeysManager { /// May panic if the [`SpendableOutputDescriptor`]s were not generated by channels which used /// this [`KeysManager`] or one of the [`InMemorySigner`] created by this [`KeysManager`]. pub fn spend_spendable_outputs(&self, descriptors: &[&SpendableOutputDescriptor], outputs: Vec, change_destination_script: ScriptBuf, feerate_sat_per_1000_weight: u32, locktime: Option, secp_ctx: &Secp256k1) -> Result { - let (mut psbt, expected_max_weight) = SpendableOutputDescriptor::create_spendable_outputs_psbt(descriptors, outputs, change_destination_script, feerate_sat_per_1000_weight, locktime, None)?; + let (mut psbt, expected_max_weight) = SpendableOutputDescriptor::create_spendable_outputs_psbt(descriptors, outputs, change_destination_script, feerate_sat_per_1000_weight, locktime)?; psbt = self.sign_spendable_outputs_psbt(descriptors, psbt, secp_ctx)?; let spend_tx = psbt.extract_tx();