From: Matt Corallo Date: Mon, 27 Nov 2023 21:37:42 +0000 (+0000) Subject: Add `channel_keys_id` to `SpendableOutputDescriptor::StaticOutput` X-Git-Tag: v0.0.119~41^2 X-Git-Url: http://git.bitcoin.ninja/?a=commitdiff_plain;h=refs%2Fheads%2F2023-11-2744-followups;p=rust-lightning Add `channel_keys_id` to `SpendableOutputDescriptor::StaticOutput` In 7f0fd868ad4e8072440f1eb79e78894de1629157, `channel_keys_id` was added as an argument to `SignerProvider::get_destination_script`, allowing implementors to generate a new script for each channel. This is great, however users then have no way to re-derive the corresponding private key when they ultimately receive a `SpendableOutputDescriptor::StaticOutput`. Instead, they have to track all the addresses as they derive them separately. In many cases this is fine, but we should support both deployments, which we do here by simply including the missing `channel_keys_id` for the user. --- diff --git a/lightning/src/chain/channelmonitor.rs b/lightning/src/chain/channelmonitor.rs index 82af15431..ed46766db 100644 --- a/lightning/src/chain/channelmonitor.rs +++ b/lightning/src/chain/channelmonitor.rs @@ -4082,6 +4082,7 @@ impl ChannelMonitorImpl { spendable_outputs.push(SpendableOutputDescriptor::StaticOutput { outpoint: OutPoint { txid: tx.txid(), index: i as u16 }, output: outp.clone(), + channel_keys_id: Some(self.channel_keys_id), }); } if let Some(ref broadcasted_holder_revokable_script) = self.broadcasted_holder_revokable_script { @@ -4110,6 +4111,7 @@ impl ChannelMonitorImpl { spendable_outputs.push(SpendableOutputDescriptor::StaticOutput { outpoint: OutPoint { txid: tx.txid(), index: i as u16 }, output: outp.clone(), + channel_keys_id: Some(self.channel_keys_id), }); } } diff --git a/lightning/src/sign/mod.rs b/lightning/src/sign/mod.rs index 17501603e..d27a64be7 100644 --- a/lightning/src/sign/mod.rs +++ b/lightning/src/sign/mod.rs @@ -202,6 +202,15 @@ pub enum SpendableOutputDescriptor { outpoint: OutPoint, /// The output which is referenced by the given outpoint. output: TxOut, + /// The `channel_keys_id` for the channel which this output came from. + /// + /// For channels which were generated on LDK 0.0.119 or later, this is the value which was + /// passed to the [`SignerProvider::get_destination_script`] call which provided this + /// output script. + /// + /// For channels which were generated prior to LDK 0.0.119, no such argument existed, + /// however this field may still be filled in if such data is available. + channel_keys_id: Option<[u8; 32]> }, /// An output to a P2WSH script which can be spent with a single signature after an `OP_CSV` /// delay. @@ -265,6 +274,7 @@ pub enum SpendableOutputDescriptor { impl_writeable_tlv_based_enum!(SpendableOutputDescriptor, (0, StaticOutput) => { (0, outpoint, required), + (1, channel_keys_id, option), (2, output, required), }, ; @@ -365,7 +375,7 @@ impl SpendableOutputDescriptor { { witness_weight -= 1; } // Guarantees a low R signature input_value += descriptor.output.value; }, - SpendableOutputDescriptor::StaticOutput { ref outpoint, ref output } => { + SpendableOutputDescriptor::StaticOutput { ref outpoint, ref output, .. } => { if !output_set.insert(*outpoint) { return Err(()); } input.push(TxIn { previous_output: outpoint.into_bitcoin_outpoint(), @@ -1640,7 +1650,7 @@ impl KeysManager { let witness = keys_cache.as_ref().unwrap().0.sign_dynamic_p2wsh_input(&psbt.unsigned_tx, input_idx, &descriptor, &secp_ctx)?; psbt.inputs[input_idx].final_script_witness = Some(witness); }, - SpendableOutputDescriptor::StaticOutput { ref outpoint, ref output } => { + SpendableOutputDescriptor::StaticOutput { ref outpoint, ref output, .. } => { let input_idx = psbt.unsigned_tx.input.iter().position(|i| i.previous_output == outpoint.into_bitcoin_outpoint()).ok_or(())?; let derivation_idx = if output.script_pubkey == self.destination_script { 1