Upgrade rust-bitcoin to 0.31
[rust-lightning] / lightning / src / sign / mod.rs
index 9b5efee4b9695cc10a3df1cef99e4d4328dc05b1..885b8840b7650d9f4f49f811195cdef09c2822a9 100644 (file)
 //! The provided output descriptors follow a custom LDK data format and are currently not fully
 //! compatible with Bitcoin Core output descriptors.
 
-use bitcoin::bip32::{ChildNumber, ExtendedPrivKey, ExtendedPubKey};
+use bitcoin::amount::Amount;
+use bitcoin::bip32::{ChildNumber, Xpriv, Xpub};
 use bitcoin::blockdata::locktime::absolute::LockTime;
 use bitcoin::blockdata::opcodes;
 use bitcoin::blockdata::script::{Builder, Script, ScriptBuf};
 use bitcoin::blockdata::transaction::{Transaction, TxIn, TxOut};
 use bitcoin::ecdsa::Signature as EcdsaSignature;
-use bitcoin::network::constants::Network;
-use bitcoin::psbt::PartiallySignedTransaction;
+use bitcoin::network::Network;
 use bitcoin::sighash;
 use bitcoin::sighash::EcdsaSighashType;
+use bitcoin::transaction::Version;
 
-use bitcoin::bech32::u5;
-use bitcoin::hash_types::WPubkeyHash;
+use bech32::u5;
 use bitcoin::hashes::sha256::Hash as Sha256;
 use bitcoin::hashes::sha256d::Hash as Sha256dHash;
 use bitcoin::hashes::{Hash, HashEngine};
@@ -34,25 +34,27 @@ use bitcoin::secp256k1::ecdsa::{RecoverableSignature, Signature};
 use bitcoin::secp256k1::schnorr;
 #[cfg(taproot)]
 use bitcoin::secp256k1::All;
-use bitcoin::secp256k1::{KeyPair, PublicKey, Scalar, Secp256k1, SecretKey, Signing};
-use bitcoin::{secp256k1, Sequence, Txid, Witness};
+use bitcoin::secp256k1::{Keypair, PublicKey, Scalar, Secp256k1, SecretKey, Signing};
+use bitcoin::{secp256k1, Psbt, Sequence, Txid, WPubkeyHash, Witness};
 
 use crate::chain::transaction::OutPoint;
 use crate::crypto::utils::{hkdf_extract_expand_twice, sign, sign_with_aux_rand};
+use crate::ln::chan_utils;
 use crate::ln::chan_utils::{
-       make_funding_redeemscript, ChannelPublicKeys, ChannelTransactionParameters, ClosingTransaction,
-       CommitmentTransaction, HTLCOutputInCommitment, HolderCommitmentTransaction,
+       get_revokeable_redeemscript, make_funding_redeemscript, ChannelPublicKeys,
+       ChannelTransactionParameters, ClosingTransaction, CommitmentTransaction,
+       HTLCOutputInCommitment, HolderCommitmentTransaction,
 };
 use crate::ln::channel::ANCHOR_OUTPUT_VALUE_SATOSHI;
 use crate::ln::channel_keys::{
-       DelayedPaymentBasepoint, DelayedPaymentKey, HtlcBasepoint, HtlcKey, RevocationBasepoint,
-       RevocationKey,
+       add_public_key_tweak, DelayedPaymentBasepoint, DelayedPaymentKey, HtlcBasepoint, HtlcKey,
+       RevocationBasepoint, RevocationKey,
 };
 #[cfg(taproot)]
 use crate::ln::msgs::PartialSignatureWithNonce;
 use crate::ln::msgs::{UnsignedChannelAnnouncement, UnsignedGossipMessage};
 use crate::ln::script::ShutdownScript;
-use crate::ln::{chan_utils, PaymentPreimage};
+use crate::ln::types::PaymentPreimage;
 use crate::offers::invoice::UnsignedBolt12Invoice;
 use crate::offers::invoice_request::UnsignedInvoiceRequest;
 use crate::util::ser::{Readable, ReadableArgs, Writeable, Writer};
@@ -61,13 +63,14 @@ use crate::util::transaction_utils;
 use crate::crypto::chacha20::ChaCha20;
 use crate::io::{self, Error};
 use crate::ln::features::ChannelTypeFeatures;
-use crate::ln::msgs::{DecodeError, MAX_VALUE_MSAT};
+use crate::ln::msgs::DecodeError;
 use crate::prelude::*;
-use crate::sign::ecdsa::{EcdsaChannelSigner, WriteableEcdsaChannelSigner};
+use crate::sign::ecdsa::EcdsaChannelSigner;
 #[cfg(taproot)]
 use crate::sign::taproot::TaprootChannelSigner;
 use crate::util::atomic_counter::AtomicCounter;
 use crate::util::invoice::construct_invoice_preimage;
+use core::convert::TryInto;
 use core::ops::Deref;
 use core::sync::atomic::{AtomicUsize, Ordering};
 #[cfg(taproot)]
@@ -108,7 +111,13 @@ 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,
+       /// The channel public keys and other parameters needed to generate a spending transaction or
+       /// to provide to a re-derived signer through [`ChannelSigner::provide_channel_parameters`].
+       ///
+       /// Added as optional, but always `Some` if the descriptor was produced in v0.0.123 or later.
+       pub channel_transaction_parameters: Option<ChannelTransactionParameters>,
 }
+
 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
@@ -127,6 +136,7 @@ impl_writeable_tlv_based!(DelayedPaymentOutputDescriptor, {
        (8, revocation_pubkey, required),
        (10, channel_keys_id, required),
        (12, channel_value_satoshis, required),
+       (13, channel_transaction_parameters, option),
 });
 
 pub(crate) const P2WPKH_WITNESS_WEIGHT: u64 = 1 /* num stack items */ +
@@ -135,6 +145,10 @@ pub(crate) const P2WPKH_WITNESS_WEIGHT: u64 = 1 /* num stack items */ +
        1 /* pubkey length */ +
        33 /* pubkey */;
 
+/// Witness weight for satisying a P2TR key-path spend.
+pub(crate) const P2TR_KEY_PATH_WITNESS_WEIGHT: u64 = 1 /* witness items */
+       + 1 /* schnorr sig len */ + 64 /* schnorr sig */;
+
 /// Information about a spendable output to our "payment key".
 ///
 /// See [`SpendableOutputDescriptor::StaticPaymentOutput`] for more details on how to spend this.
@@ -155,6 +169,7 @@ pub struct StaticPaymentOutputDescriptor {
        /// Added as optional, but always `Some` if the descriptor was produced in v0.0.117 or later.
        pub channel_transaction_parameters: Option<ChannelTransactionParameters>,
 }
+
 impl StaticPaymentOutputDescriptor {
        /// Returns the `witness_script` of the spendable output.
        ///
@@ -299,37 +314,116 @@ impl_writeable_tlv_based_enum!(SpendableOutputDescriptor,
 
 impl SpendableOutputDescriptor {
        /// Turns this into a [`bitcoin::psbt::Input`] which can be used to create a
-       /// [`PartiallySignedTransaction`] which spends the given descriptor.
+       /// [`Psbt`] which spends the given descriptor.
        ///
        /// Note that this does not include any signatures, just the information required to
        /// construct the transaction and sign it.
        ///
        /// 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) -> bitcoin::psbt::Input {
+       ///
+       /// The proprietary field is used to store add tweak for the signing key of this transaction.
+       /// See the [`DelayedPaymentBasepoint::derive_add_tweak`] docs for more info on add tweak and how to use it.
+       ///
+       /// To get the proprietary field use:
+       /// ```
+       /// use bitcoin::psbt::{Psbt};
+       /// use bitcoin::hashes::hex::FromHex;
+       ///
+       /// # let s = "70736274ff0100520200000001dee978529ab3e61a2987bea5183713d0e6d5ceb5ac81100fdb54a1a2\
+       ///     #                69cef505000000000090000000011f26000000000000160014abb3ab63280d4ccc5c11d6b50fd427a8\
+       ///     #                e19d6470000000000001012b10270000000000002200200afe4736760d814a2651bae63b572d935d9a\
+       /// #            b74a1a16c01774e341a32afa763601054d63210394a27a700617f5b7aee72bd4f8076b5770a582b7fb\
+       ///     #                d1d4ee2ea3802cd3cfbe2067029000b27521034629b1c8fdebfaeb58a74cd181f485e2c462e594cb30\
+       ///     #                34dee655875f69f6c7c968ac20fc144c444b5f7370656e6461626c655f6f7574707574006164645f74\
+       ///     #                7765616b20a86534f38ad61dc580ef41c3886204adf0911b81619c1ad7a2f5b5de39a2ba600000";
+       /// # let psbt = Psbt::deserialize(<Vec<u8> as FromHex>::from_hex(s).unwrap().as_slice()).unwrap();
+       /// let key = bitcoin::psbt::raw::ProprietaryKey {
+       ///     prefix: "LDK_spendable_output".as_bytes().to_vec(),
+       ///     subtype: 0,
+       ///     key: "add_tweak".as_bytes().to_vec(),
+       /// };
+       /// let value = psbt
+       ///     .inputs
+       ///     .first()
+       ///     .expect("Unable to get add tweak as there are no inputs")
+       ///     .proprietary
+       ///     .get(&key)
+       ///     .map(|x| x.to_owned());
+       /// ```
+       pub fn to_psbt_input<T: secp256k1::Signing>(
+               &self, secp_ctx: &Secp256k1<T>,
+       ) -> bitcoin::psbt::Input {
                match self {
                        SpendableOutputDescriptor::StaticOutput { output, .. } => {
                                // Is a standard P2WPKH, no need for witness script
                                bitcoin::psbt::Input { witness_utxo: Some(output.clone()), ..Default::default() }
                        },
-                       SpendableOutputDescriptor::DelayedPaymentOutput(descriptor) => {
-                               // TODO we could add the witness script as well
+                       SpendableOutputDescriptor::DelayedPaymentOutput(DelayedPaymentOutputDescriptor {
+                               channel_transaction_parameters,
+                               per_commitment_point,
+                               revocation_pubkey,
+                               to_self_delay,
+                               output,
+                               ..
+                       }) => {
+                               let delayed_payment_basepoint = channel_transaction_parameters
+                                       .as_ref()
+                                       .map(|params| params.holder_pubkeys.delayed_payment_basepoint);
+
+                               let (witness_script, add_tweak) =
+                                       if let Some(basepoint) = delayed_payment_basepoint.as_ref() {
+                                               // Required to derive signing key: privkey = basepoint_secret + SHA256(per_commitment_point || basepoint)
+                                               let add_tweak = basepoint.derive_add_tweak(&per_commitment_point);
+                                               let payment_key = DelayedPaymentKey(add_public_key_tweak(
+                                                       secp_ctx,
+                                                       &basepoint.to_public_key(),
+                                                       &add_tweak,
+                                               ));
+
+                                               (
+                                                       Some(get_revokeable_redeemscript(
+                                                               &revocation_pubkey,
+                                                               *to_self_delay,
+                                                               &payment_key,
+                                                       )),
+                                                       Some(add_tweak),
+                                               )
+                                       } else {
+                                               (None, None)
+                                       };
+
                                bitcoin::psbt::Input {
-                                       witness_utxo: Some(descriptor.output.clone()),
+                                       witness_utxo: Some(output.clone()),
+                                       witness_script,
+                                       proprietary: add_tweak
+                                               .map(|add_tweak| {
+                                                       [(
+                                                               bitcoin::psbt::raw::ProprietaryKey {
+                                                                       // A non standard namespace for spendable outputs, used to store the tweak needed
+                                                                       // to derive the private key
+                                                                       prefix: "LDK_spendable_output".as_bytes().to_vec(),
+                                                                       subtype: 0,
+                                                                       key: "add_tweak".as_bytes().to_vec(),
+                                                               },
+                                                               add_tweak.as_byte_array().to_vec(),
+                                                       )]
+                                                       .into_iter()
+                                                       .collect()
+                                               })
+                                               .unwrap_or_default(),
                                        ..Default::default()
                                }
                        },
-                       SpendableOutputDescriptor::StaticPaymentOutput(descriptor) => {
-                               // TODO we could add the witness script as well
-                               bitcoin::psbt::Input {
-                                       witness_utxo: Some(descriptor.output.clone()),
-                                       ..Default::default()
-                               }
+                       SpendableOutputDescriptor::StaticPaymentOutput(descriptor) => bitcoin::psbt::Input {
+                               witness_utxo: Some(descriptor.output.clone()),
+                               witness_script: descriptor.witness_script(),
+                               ..Default::default()
                        },
                }
        }
 
-       /// Creates an unsigned [`PartiallySignedTransaction`] which spends the given descriptors to
+       /// Creates an unsigned [`Psbt`] which spends the given descriptors to
        /// the given outputs, plus an output to the given change destination (if sufficient
        /// change value remains). The PSBT will have a feerate, at least, of the given value.
        ///
@@ -345,13 +439,13 @@ 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<TxOut>,
+       pub fn create_spendable_outputs_psbt<T: secp256k1::Signing>(
+               secp_ctx: &Secp256k1<T>, descriptors: &[&SpendableOutputDescriptor], outputs: Vec<TxOut>,
                change_destination_script: ScriptBuf, feerate_sat_per_1000_weight: u32,
                locktime: Option<LockTime>,
-       ) -> Result<(PartiallySignedTransaction, u64), ()> {
+       ) -> Result<(Psbt, u64), ()> {
                let mut input = Vec::with_capacity(descriptors.len());
-               let mut input_value = 0;
+               let mut input_value = Amount::ZERO;
                let mut witness_weight = 0;
                let mut output_set = hash_set_with_capacity(descriptors.len());
                for outp in descriptors {
@@ -420,12 +514,12 @@ impl SpendableOutputDescriptor {
                                        input_value += output.value;
                                },
                        }
-                       if input_value > MAX_VALUE_MSAT / 1000 {
+                       if input_value > Amount::MAX_MONEY {
                                return Err(());
                        }
                }
                let mut tx = Transaction {
-                       version: 2,
+                       version: Version::TWO,
                        lock_time: locktime.unwrap_or(LockTime::ZERO),
                        input,
                        output: outputs,
@@ -438,8 +532,9 @@ impl SpendableOutputDescriptor {
                        change_destination_script,
                )?;
 
-               let psbt_inputs = descriptors.iter().map(|d| d.to_psbt_input()).collect::<Vec<_>>();
-               let psbt = PartiallySignedTransaction {
+               let psbt_inputs =
+                       descriptors.iter().map(|d| d.to_psbt_input(&secp_ctx)).collect::<Vec<_>>();
+               let psbt = Psbt {
                        inputs: psbt_inputs,
                        outputs: vec![Default::default(); tx.output.len()],
                        unsigned_tx: tx,
@@ -525,8 +620,8 @@ impl HTLCDescriptor {
                &self, secp: &Secp256k1<C>,
        ) -> TxOut {
                TxOut {
-                       script_pubkey: self.witness_script(secp).to_v0_p2wsh(),
-                       value: self.htlc.amount_msat / 1000,
+                       script_pubkey: self.witness_script(secp).to_p2wsh(),
+                       value: self.htlc.to_bitcoin_amount(),
                }
        }
 
@@ -614,9 +709,7 @@ impl HTLCDescriptor {
        }
 
        /// Derives the channel signer required to sign the HTLC input.
-       pub fn derive_channel_signer<S: WriteableEcdsaChannelSigner, SP: Deref>(
-               &self, signer_provider: &SP,
-       ) -> S
+       pub fn derive_channel_signer<S: EcdsaChannelSigner, SP: Deref>(&self, signer_provider: &SP) -> S
        where
                SP::Target: SignerProvider<EcdsaSigner = S>,
        {
@@ -829,6 +922,8 @@ pub trait OutputSpender {
 
 // Primarily needed in doctests because of https://github.com/rust-lang/rust/issues/67295
 /// A dynamic [`SignerProvider`] temporarily needed for doc tests.
+///
+/// This is not exported to bindings users as it is not intended for public consumption.
 #[cfg(taproot)]
 #[doc(hidden)]
 #[deprecated(note = "Remove once taproot cfg is removed")]
@@ -836,6 +931,8 @@ pub type DynSignerProvider =
        dyn SignerProvider<EcdsaSigner = InMemorySigner, TaprootSigner = InMemorySigner>;
 
 /// A dynamic [`SignerProvider`] temporarily needed for doc tests.
+///
+/// This is not exported to bindings users as it is not intended for public consumption.
 #[cfg(not(taproot))]
 #[doc(hidden)]
 #[deprecated(note = "Remove once taproot cfg is removed")]
@@ -843,8 +940,8 @@ pub type DynSignerProvider = dyn SignerProvider<EcdsaSigner = InMemorySigner>;
 
 /// A trait that can return signer instances for individual channels.
 pub trait SignerProvider {
-       /// A type which implements [`WriteableEcdsaChannelSigner`] which will be returned by [`Self::derive_channel_signer`].
-       type EcdsaSigner: WriteableEcdsaChannelSigner;
+       /// A type which implements [`EcdsaChannelSigner`] which will be returned by [`Self::derive_channel_signer`].
+       type EcdsaSigner: EcdsaChannelSigner;
        #[cfg(taproot)]
        /// A type which implements [`TaprootChannelSigner`]
        type TaprootSigner: TaprootChannelSigner;
@@ -871,7 +968,7 @@ pub trait SignerProvider {
 
        /// Reads a [`Signer`] for this [`SignerProvider`] from the given input stream.
        /// This is only called during deserialization of other objects which contain
-       /// [`WriteableEcdsaChannelSigner`]-implementing objects (i.e., [`ChannelMonitor`]s and [`ChannelManager`]s).
+       /// [`EcdsaChannelSigner`]-implementing objects (i.e., [`ChannelMonitor`]s and [`ChannelManager`]s).
        /// The bytes are exactly those which `<Self::Signer as Writeable>::write()` writes, and
        /// contain no versioning scheme. You may wish to include your own version prefix and ensure
        /// you've read all of the provided bytes to ensure no corruption occurred.
@@ -915,7 +1012,7 @@ pub trait ChangeDestinationSource {
        fn get_change_destination_script(&self) -> Result<ScriptBuf, ()>;
 }
 
-/// A simple implementation of [`WriteableEcdsaChannelSigner`] that just keeps the private keys in memory.
+/// A simple implementation of [`EcdsaChannelSigner`] that just keeps the private keys in memory.
 ///
 /// This implementation performs no policy checks and is insufficient by itself as
 /// a secure external signer.
@@ -1134,7 +1231,7 @@ impl InMemorySigner {
                };
                let sighash = hash_to_message!(
                        &sighash::SighashCache::new(spend_tx)
-                               .segwit_signature_hash(
+                               .p2wsh_signature_hash(
                                        input_idx,
                                        &witness_script,
                                        descriptor.output.value,
@@ -1144,9 +1241,9 @@ impl InMemorySigner {
                );
                let remotesig = sign_with_aux_rand(secp_ctx, &sighash, &self.payment_key, &self);
                let payment_script = if supports_anchors_zero_fee_htlc_tx {
-                       witness_script.to_v0_p2wsh()
+                       witness_script.to_p2wsh()
                } else {
-                       ScriptBuf::new_v0_p2wpkh(&remotepubkey.wpubkey_hash().unwrap())
+                       ScriptBuf::new_p2wpkh(&remotepubkey.wpubkey_hash().unwrap())
                };
 
                if payment_script != descriptor.output.script_pubkey {
@@ -1210,7 +1307,7 @@ impl InMemorySigner {
                );
                let sighash = hash_to_message!(
                        &sighash::SighashCache::new(spend_tx)
-                               .segwit_signature_hash(
+                               .p2wsh_signature_hash(
                                        input_idx,
                                        &witness_script,
                                        descriptor.output.value,
@@ -1339,10 +1436,10 @@ impl EcdsaChannelSigner for InMemorySigner {
                        };
                        let htlc_sighash = hash_to_message!(
                                &sighash::SighashCache::new(&htlc_tx)
-                                       .segwit_signature_hash(
+                                       .p2wsh_signature_hash(
                                                0,
                                                &htlc_redeemscript,
-                                               htlc.amount_msat / 1000,
+                                               htlc.to_bitcoin_amount(),
                                                htlc_sighashtype
                                        )
                                        .unwrap()[..]
@@ -1426,7 +1523,12 @@ impl EcdsaChannelSigner for InMemorySigner {
                let mut sighash_parts = sighash::SighashCache::new(justice_tx);
                let sighash = hash_to_message!(
                        &sighash_parts
-                               .segwit_signature_hash(input, &witness_script, amount, EcdsaSighashType::All)
+                               .p2wsh_signature_hash(
+                                       input,
+                                       &witness_script,
+                                       Amount::from_sat(amount),
+                                       EcdsaSighashType::All
+                               )
                                .unwrap()[..]
                );
                return Ok(sign_with_aux_rand(secp_ctx, &sighash, &revocation_key, &self));
@@ -1471,7 +1573,12 @@ impl EcdsaChannelSigner for InMemorySigner {
                let mut sighash_parts = sighash::SighashCache::new(justice_tx);
                let sighash = hash_to_message!(
                        &sighash_parts
-                               .segwit_signature_hash(input, &witness_script, amount, EcdsaSighashType::All)
+                               .p2wsh_signature_hash(
+                                       input,
+                                       &witness_script,
+                                       Amount::from_sat(amount),
+                                       EcdsaSighashType::All
+                               )
                                .unwrap()[..]
                );
                return Ok(sign_with_aux_rand(secp_ctx, &sighash, &revocation_key, &self));
@@ -1483,10 +1590,10 @@ impl EcdsaChannelSigner for InMemorySigner {
        ) -> Result<Signature, ()> {
                let witness_script = htlc_descriptor.witness_script(secp_ctx);
                let sighash = &sighash::SighashCache::new(&*htlc_tx)
-                       .segwit_signature_hash(
+                       .p2wsh_signature_hash(
                                input,
                                &witness_script,
-                               htlc_descriptor.htlc.amount_msat / 1000,
+                               htlc_descriptor.htlc.to_bitcoin_amount(),
                                EcdsaSighashType::All,
                        )
                        .map_err(|_| ())?;
@@ -1529,7 +1636,12 @@ impl EcdsaChannelSigner for InMemorySigner {
                let mut sighash_parts = sighash::SighashCache::new(htlc_tx);
                let sighash = hash_to_message!(
                        &sighash_parts
-                               .segwit_signature_hash(input, &witness_script, amount, EcdsaSighashType::All)
+                               .p2wsh_signature_hash(
+                                       input,
+                                       &witness_script,
+                                       Amount::from_sat(amount),
+                                       EcdsaSighashType::All
+                               )
                                .unwrap()[..]
                );
                Ok(sign_with_aux_rand(secp_ctx, &sighash, &htlc_key, &self))
@@ -1557,10 +1669,10 @@ impl EcdsaChannelSigner for InMemorySigner {
                let witness_script =
                        chan_utils::get_anchor_redeemscript(&self.holder_channel_pubkeys.funding_pubkey);
                let sighash = sighash::SighashCache::new(&*anchor_tx)
-                       .segwit_signature_hash(
+                       .p2wsh_signature_hash(
                                input,
                                &witness_script,
-                               ANCHOR_OUTPUT_VALUE_SATOSHI,
+                               Amount::from_sat(ANCHOR_OUTPUT_VALUE_SATOSHI),
                                EcdsaSighashType::All,
                        )
                        .unwrap();
@@ -1643,8 +1755,6 @@ const SERIALIZATION_VERSION: u8 = 1;
 
 const MIN_SERIALIZATION_VERSION: u8 = 1;
 
-impl WriteableEcdsaChannelSigner for InMemorySigner {}
-
 impl Writeable for InMemorySigner {
        fn write<W: Writer>(&self, writer: &mut W) -> Result<(), Error> {
                write_ver_prefix!(writer, SERIALIZATION_VERSION, MIN_SERIALIZATION_VERSION);
@@ -1729,7 +1839,7 @@ pub struct KeysManager {
        inbound_payment_key: KeyMaterial,
        destination_script: ScriptBuf,
        shutdown_pubkey: PublicKey,
-       channel_master_key: ExtendedPrivKey,
+       channel_master_key: Xpriv,
        channel_child_index: AtomicUsize,
 
        entropy_source: RandomBytes,
@@ -1760,21 +1870,19 @@ impl KeysManager {
        pub fn new(seed: &[u8; 32], starting_time_secs: u64, starting_time_nanos: u32) -> Self {
                let secp_ctx = Secp256k1::new();
                // Note that when we aren't serializing the key, network doesn't matter
-               match ExtendedPrivKey::new_master(Network::Testnet, seed) {
+               match Xpriv::new_master(Network::Testnet, seed) {
                        Ok(master_key) => {
                                let node_secret = master_key
-                                       .ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(0).unwrap())
+                                       .derive_priv(&secp_ctx, &ChildNumber::from_hardened_idx(0).unwrap())
                                        .expect("Your RNG is busted")
                                        .private_key;
                                let node_id = PublicKey::from_secret_key(&secp_ctx, &node_secret);
                                let destination_script = match master_key
-                                       .ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(1).unwrap())
+                                       .derive_priv(&secp_ctx, &ChildNumber::from_hardened_idx(1).unwrap())
                                {
                                        Ok(destination_key) => {
                                                let wpubkey_hash = WPubkeyHash::hash(
-                                                       &ExtendedPubKey::from_priv(&secp_ctx, &destination_key)
-                                                               .to_pub()
-                                                               .to_bytes(),
+                                                       &Xpub::from_priv(&secp_ctx, &destination_key).to_pub().to_bytes(),
                                                );
                                                Builder::new()
                                                        .push_opcode(opcodes::all::OP_PUSHBYTES_0)
@@ -1784,18 +1892,16 @@ impl KeysManager {
                                        Err(_) => panic!("Your RNG is busted"),
                                };
                                let shutdown_pubkey = match master_key
-                                       .ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(2).unwrap())
+                                       .derive_priv(&secp_ctx, &ChildNumber::from_hardened_idx(2).unwrap())
                                {
-                                       Ok(shutdown_key) => {
-                                               ExtendedPubKey::from_priv(&secp_ctx, &shutdown_key).public_key
-                                       },
+                                       Ok(shutdown_key) => Xpub::from_priv(&secp_ctx, &shutdown_key).public_key,
                                        Err(_) => panic!("Your RNG is busted"),
                                };
                                let channel_master_key = master_key
-                                       .ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(3).unwrap())
+                                       .derive_priv(&secp_ctx, &ChildNumber::from_hardened_idx(3).unwrap())
                                        .expect("Your RNG is busted");
                                let inbound_payment_key: SecretKey = master_key
-                                       .ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(5).unwrap())
+                                       .derive_priv(&secp_ctx, &ChildNumber::from_hardened_idx(5).unwrap())
                                        .expect("Your RNG is busted")
                                        .private_key;
                                let mut inbound_pmt_key_bytes = [0; 32];
@@ -1840,7 +1946,7 @@ impl KeysManager {
                self.node_secret
        }
 
-       /// Derive an old [`WriteableEcdsaChannelSigner`] containing per-channel secrets based on a key derivation parameters.
+       /// Derive an old [`EcdsaChannelSigner`] containing per-channel secrets based on a key derivation parameters.
        pub fn derive_channel_keys(
                &self, channel_value_satoshis: u64, params: &[u8; 32],
        ) -> InMemorySigner {
@@ -1854,9 +1960,9 @@ impl KeysManager {
                // starting_time provided in the constructor) to be unique.
                let child_privkey = self
                        .channel_master_key
-                       .ckd_priv(
+                       .derive_priv(
                                &self.secp_ctx,
-                               ChildNumber::from_hardened_idx((chan_id as u32) % (1 << 31))
+                               &ChildNumber::from_hardened_idx((chan_id as u32) % (1 << 31))
                                        .expect("key space exhausted"),
                        )
                        .expect("Your RNG is busted");
@@ -1901,7 +2007,7 @@ impl KeysManager {
                )
        }
 
-       /// Signs the given [`PartiallySignedTransaction`] which spends the given [`SpendableOutputDescriptor`]s.
+       /// Signs the given [`Psbt`] which spends the given [`SpendableOutputDescriptor`]s.
        /// The resulting inputs will be finalized and the PSBT will be ready for broadcast if there
        /// are no other inputs that need signing.
        ///
@@ -1910,9 +2016,8 @@ 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 sign_spendable_outputs_psbt<C: Signing>(
-               &self, descriptors: &[&SpendableOutputDescriptor], mut psbt: PartiallySignedTransaction,
-               secp_ctx: &Secp256k1<C>,
-       ) -> Result<PartiallySignedTransaction, ()> {
+               &self, descriptors: &[&SpendableOutputDescriptor], mut psbt: Psbt, secp_ctx: &Secp256k1<C>,
+       ) -> Result<Psbt, ()> {
                let mut keys_cache: Option<(InMemorySigner, [u8; 32])> = None;
                for outp in descriptors {
                        let get_input_idx = |outpoint: &OutPoint| {
@@ -1974,11 +2079,11 @@ impl KeysManager {
                                                if output.script_pubkey == self.destination_script { 1 } else { 2 };
                                        let secret = {
                                                // Note that when we aren't serializing the key, network doesn't matter
-                                               match ExtendedPrivKey::new_master(Network::Testnet, &self.seed) {
+                                               match Xpriv::new_master(Network::Testnet, &self.seed) {
                                                        Ok(master_key) => {
-                                                               match master_key.ckd_priv(
+                                                               match master_key.derive_priv(
                                                                        &secp_ctx,
-                                                                       ChildNumber::from_hardened_idx(derivation_idx)
+                                                                       &ChildNumber::from_hardened_idx(derivation_idx)
                                                                                .expect("key space exhausted"),
                                                                ) {
                                                                        Ok(key) => key,
@@ -1988,7 +2093,7 @@ impl KeysManager {
                                                        Err(_) => panic!("Your rng is busted"),
                                                }
                                        };
-                                       let pubkey = ExtendedPubKey::from_priv(&secp_ctx, &secret).to_pub();
+                                       let pubkey = Xpub::from_priv(&secp_ctx, &secret).to_pub();
                                        if derivation_idx == 2 {
                                                assert_eq!(pubkey.inner, self.shutdown_pubkey);
                                        }
@@ -2004,7 +2109,7 @@ impl KeysManager {
 
                                        let sighash = hash_to_message!(
                                                &sighash::SighashCache::new(&psbt.unsigned_tx)
-                                                       .segwit_signature_hash(
+                                                       .p2wsh_signature_hash(
                                                                input_idx,
                                                                &witness_script,
                                                                output.value,
@@ -2075,7 +2180,7 @@ impl NodeSigner for KeysManager {
                &self, invoice_request: &UnsignedInvoiceRequest,
        ) -> Result<schnorr::Signature, ()> {
                let message = invoice_request.tagged_hash().as_digest();
-               let keys = KeyPair::from_secret_key(&self.secp_ctx, &self.node_secret);
+               let keys = Keypair::from_secret_key(&self.secp_ctx, &self.node_secret);
                let aux_rand = self.get_secure_random_bytes();
                Ok(self.secp_ctx.sign_schnorr_with_aux_rand(message, &keys, &aux_rand))
        }
@@ -2084,7 +2189,7 @@ impl NodeSigner for KeysManager {
                &self, invoice: &UnsignedBolt12Invoice,
        ) -> Result<schnorr::Signature, ()> {
                let message = invoice.tagged_hash().as_digest();
-               let keys = KeyPair::from_secret_key(&self.secp_ctx, &self.node_secret);
+               let keys = Keypair::from_secret_key(&self.secp_ctx, &self.node_secret);
                let aux_rand = self.get_secure_random_bytes();
                Ok(self.secp_ctx.sign_schnorr_with_aux_rand(message, &keys, &aux_rand))
        }
@@ -2112,6 +2217,7 @@ impl OutputSpender for KeysManager {
        ) -> Result<Transaction, ()> {
                let (mut psbt, expected_max_weight) =
                        SpendableOutputDescriptor::create_spendable_outputs_psbt(
+                               secp_ctx,
                                descriptors,
                                outputs,
                                change_destination_script,
@@ -2120,7 +2226,7 @@ impl OutputSpender for KeysManager {
                        )?;
                psbt = self.sign_spendable_outputs_psbt(descriptors, psbt, secp_ctx)?;
 
-               let spend_tx = psbt.extract_tx();
+               let spend_tx = psbt.extract_tx_unchecked_fee_rate();
 
                debug_assert!(expected_max_weight >= spend_tx.weight().to_wu());
                // Note that witnesses with a signature vary somewhat in size, so allow