Support sending payments with a retry strategy in ChannelManager
[rust-lightning] / lightning / src / chain / keysinterface.rs
index 1426ff5ce887f4d0ef440874ab9df00849de978a..7063a38c4af33b862c810f710c5a3ee19abc3e1c 100644 (file)
@@ -34,14 +34,14 @@ use bitcoin::{PackedLockTime, secp256k1, Sequence, Witness};
 
 use crate::util::transaction_utils;
 use crate::util::crypto::{hkdf_extract_expand_twice, sign};
-use crate::util::ser::{Writeable, Writer, Readable, ReadableArgs};
+use crate::util::ser::{Writeable, Writer, Readable};
 #[cfg(anchors)]
 use crate::util::events::HTLCDescriptor;
 use crate::chain::transaction::OutPoint;
 use crate::ln::channel::ANCHOR_OUTPUT_VALUE_SATOSHI;
 use crate::ln::{chan_utils, PaymentPreimage};
 use crate::ln::chan_utils::{HTLCOutputInCommitment, make_funding_redeemscript, ChannelPublicKeys, HolderCommitmentTransaction, ChannelTransactionParameters, CommitmentTransaction, ClosingTransaction};
-use crate::ln::msgs::UnsignedChannelAnnouncement;
+use crate::ln::msgs::{UnsignedChannelAnnouncement, UnsignedGossipMessage};
 use crate::ln::script::ShutdownScript;
 
 use crate::prelude::*;
@@ -137,14 +137,14 @@ impl_writeable_tlv_based!(StaticPaymentOutputDescriptor, {
 /// [`SpendableOutputs`]: crate::util::events::Event::SpendableOutputs
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub enum SpendableOutputDescriptor {
-       /// An output to a script which was provided via [`KeysInterface`] directly, either from
+       /// An output to a script which was provided via [`SignerProvider`] directly, either from
        /// [`get_destination_script`] or [`get_shutdown_scriptpubkey`], thus you should already
        /// know how to spend it. No secret keys are provided as LDK was never given any key.
        /// These may include outputs from a transaction punishing our counterparty or claiming an HTLC
        /// on-chain using the payment preimage or after it has timed out.
        ///
-       /// [`get_shutdown_scriptpubkey`]: KeysInterface::get_shutdown_scriptpubkey
-       /// [`get_destination_script`]: KeysInterface::get_shutdown_scriptpubkey
+       /// [`get_shutdown_scriptpubkey`]: SignerProvider::get_shutdown_scriptpubkey
+       /// [`get_destination_script`]: SignerProvider::get_shutdown_scriptpubkey
        StaticOutput {
                /// The outpoint which is spendable.
                outpoint: OutPoint,
@@ -383,21 +383,25 @@ pub trait BaseSign {
        fn sign_holder_anchor_input(
                &self, anchor_tx: &Transaction, input: usize, secp_ctx: &Secp256k1<secp256k1::All>,
        ) -> Result<Signature, ()>;
-       /// Signs a channel announcement message with our funding key and our node secret key (aka
-       /// node_id or network_key), proving it comes from one of the channel participants.
+       /// Signs a channel announcement message with our funding key proving it comes from one of the
+       /// channel participants.
        ///
-       /// The first returned signature should be from our node secret key, the second from our
-       /// funding key.
+       /// Channel announcements also require a signature from each node's network key. Our node
+       /// signature is computed through [`NodeSigner::sign_gossip_message`].
        ///
        /// Note that if this fails or is rejected, the channel will not be publicly announced and
        /// our counterparty may (though likely will not) close the channel on us for violating the
        /// protocol.
-       fn sign_channel_announcement(&self, msg: &UnsignedChannelAnnouncement, secp_ctx: &Secp256k1<secp256k1::All>)
-               -> Result<(Signature, Signature), ()>;
+       fn sign_channel_announcement_with_funding_key(
+               &self, msg: &UnsignedChannelAnnouncement, secp_ctx: &Secp256k1<secp256k1::All>
+       ) -> Result<Signature, ()>;
        /// Set the counterparty static channel data, including basepoints,
-       /// `counterparty_selected`/`holder_selected_contest_delay` and funding outpoint. Since these
-       /// are static channel data, they MUST NOT be allowed to change to different values once set,
-       /// as LDK may call this method more than once.
+       /// `counterparty_selected`/`holder_selected_contest_delay` and funding outpoint.
+       ///
+       /// This data is static, and will never change for a channel once set. For a given [`BaseSign`]
+       /// instance, LDK will call this method exactly once - either immediately after construction
+       /// (not including if done via [`SignerProvider::read_chan_signer`]) or when the funding
+       /// information has been generated.
        ///
        /// channel_parameters.is_populated() MUST be true.
        fn provide_channel_parameters(&mut self, channel_parameters: &ChannelTransactionParameters);
@@ -414,7 +418,7 @@ pub trait Sign: BaseSign + Writeable {}
 
 /// Specifies the recipient of an invoice.
 ///
-/// This indicates to [`KeysInterface::sign_invoice`] what node secret key should be used to sign
+/// This indicates to [`NodeSigner::sign_invoice`] what node secret key should be used to sign
 /// the invoice.
 pub enum Recipient {
        /// The invoice should be signed with the local node secret key.
@@ -426,69 +430,91 @@ pub enum Recipient {
        PhantomNode,
 }
 
-/// A trait to describe an object which can get user secrets and key material.
-pub trait KeysInterface {
-       /// A type which implements [`Sign`] which will be returned by [`Self::derive_channel_signer`].
-       type Signer : Sign;
-       /// Get node secret key based on the provided [`Recipient`].
+/// A trait that describes a source of entropy.
+pub trait EntropySource {
+       /// Gets a unique, cryptographically-secure, random 32-byte value. This method must return a
+       /// different value each time it is called.
+       fn get_secure_random_bytes(&self) -> [u8; 32];
+}
+
+/// A trait that can handle cryptographic operations at the scope level of a node.
+pub trait NodeSigner {
+       /// Get secret key material as bytes for use in encrypting and decrypting inbound payment data.
        ///
-       /// The `node_id`/`network_key` is the public key that corresponds to this secret key.
+       /// If the implementor of this trait supports [phantom node payments], then every node that is
+       /// intended to be included in the phantom invoice route hints must return the same value from
+       /// this method.
+       // This is because LDK avoids storing inbound payment data by encrypting payment data in the
+       // payment hash and/or payment secret, therefore for a payment to be receivable by multiple
+       // nodes, they must share the key that encrypts this payment data.
        ///
-       /// This method must return the same value each time it is called with a given [`Recipient`]
-       /// parameter.
+       /// This method must return the same value each time it is called.
        ///
-       /// Errors if the [`Recipient`] variant is not supported by the implementation.
-       fn get_node_secret(&self, recipient: Recipient) -> Result<SecretKey, ()>;
-       /// Get node id based on the provided [`Recipient`]. This public key corresponds to the secret in
-       /// [`get_node_secret`].
+       /// [phantom node payments]: PhantomKeysManager
+       fn get_inbound_payment_key_material(&self) -> KeyMaterial;
+
+       /// Get node id based on the provided [`Recipient`].
        ///
        /// This method must return the same value each time it is called with a given [`Recipient`]
        /// parameter.
        ///
        /// Errors if the [`Recipient`] variant is not supported by the implementation.
-       ///
-       /// [`get_node_secret`]: Self::get_node_secret
-       fn get_node_id(&self, recipient: Recipient) -> Result<PublicKey, ()> {
-               let secp_ctx = Secp256k1::signing_only();
-               Ok(PublicKey::from_secret_key(&secp_ctx, &self.get_node_secret(recipient)?))
-       }
-       /// Gets the ECDH shared secret of our [`node secret`] and `other_key`, multiplying by `tweak` if
+       fn get_node_id(&self, recipient: Recipient) -> Result<PublicKey, ()>;
+
+       /// Gets the ECDH shared secret of our node secret and `other_key`, multiplying by `tweak` if
        /// one is provided. Note that this tweak can be applied to `other_key` instead of our node
        /// secret, though this is less efficient.
        ///
-       /// Errors if the [`Recipient`] variant is not supported by the implementation.
+       /// Note that if this fails while attempting to forward an HTLC, LDK will panic. The error
+       /// should be resolved to allow LDK to resume forwarding HTLCs.
        ///
-       /// [`node secret`]: Self::get_node_secret
+       /// Errors if the [`Recipient`] variant is not supported by the implementation.
        fn ecdh(&self, recipient: Recipient, other_key: &PublicKey, tweak: Option<&Scalar>) -> Result<SharedSecret, ()>;
-       /// Get a script pubkey which we send funds to when claiming on-chain contestable outputs.
+
+       /// Sign an invoice.
        ///
-       /// This method should return a different value each time it is called, to avoid linking
-       /// on-chain funds across channels as controlled to the same user.
-       fn get_destination_script(&self) -> Script;
-       /// Get a script pubkey which we will send funds to when closing a channel.
+       /// By parameterizing by the raw invoice bytes instead of the hash, we allow implementors of
+       /// this trait to parse the invoice and make sure they're signing what they expect, rather than
+       /// blindly signing the hash.
        ///
-       /// This method should return a different value each time it is called, to avoid linking
-       /// on-chain funds across channels as controlled to the same user.
-       fn get_shutdown_scriptpubkey(&self) -> ShutdownScript;
-       /// Get a new set of [`Sign`] for per-channel secrets. These MUST be unique even if you
-       /// restarted with some stale data!
+       /// The `hrp_bytes` are ASCII bytes, while the `invoice_data` is base32.
+       ///
+       /// The secret key used to sign the invoice is dependent on the [`Recipient`].
+       ///
+       /// Errors if the [`Recipient`] variant is not supported by the implementation.
+       fn sign_invoice(&self, hrp_bytes: &[u8], invoice_data: &[u5], recipient: Recipient) -> Result<RecoverableSignature, ()>;
+
+       /// Sign a gossip message.
+       ///
+       /// Note that if this fails, LDK may panic and the message will not be broadcast to the network
+       /// or a possible channel counterparty. If LDK panics, the error should be resolved to allow the
+       /// message to be broadcast, as otherwise it may prevent one from receiving funds over the
+       /// corresponding channel.
+       fn sign_gossip_message(&self, msg: UnsignedGossipMessage) -> Result<Signature, ()>;
+}
+
+/// A trait that can return signer instances for individual channels.
+pub trait SignerProvider {
+       /// A type which implements [`Sign`] which will be returned by [`Self::derive_channel_signer`].
+       type Signer : Sign;
+
+       /// Generates a unique `channel_keys_id` that can be used to obtain a [`Self::Signer`] through
+       /// [`SignerProvider::derive_channel_signer`]. The `user_channel_id` is provided to allow
+       /// implementations of [`SignerProvider`] to maintain a mapping between itself and the generated
+       /// `channel_keys_id`.
        ///
        /// This method must return a different value each time it is called.
        fn generate_channel_keys_id(&self, inbound: bool, channel_value_satoshis: u64, user_channel_id: u128) -> [u8; 32];
+
        /// Derives the private key material backing a `Signer`.
        ///
        /// To derive a new `Signer`, a fresh `channel_keys_id` should be obtained through
-       /// [`KeysInterface::generate_channel_keys_id`]. Otherwise, an existing `Signer` can be
+       /// [`SignerProvider::generate_channel_keys_id`]. Otherwise, an existing `Signer` can be
        /// re-derived from its `channel_keys_id`, which can be obtained through its trait method
        /// [`BaseSign::channel_keys_id`].
        fn derive_channel_signer(&self, channel_value_satoshis: u64, channel_keys_id: [u8; 32]) -> Self::Signer;
-       /// Gets a unique, cryptographically-secure, random 32 byte value. This is used for encrypting
-       /// onion packets and for temporary channel IDs. There is no requirement that these be
-       /// persisted anywhere, though they must be unique across restarts.
-       ///
-       /// This method must return a different value each time it is called.
-       fn get_secure_random_bytes(&self) -> [u8; 32];
-       /// Reads a [`Signer`] for this [`KeysInterface`] from the given input stream.
+
+       /// Reads a [`Signer`] for this [`SignerProvider`] from the given input stream.
        /// This is only called during deserialization of other objects which contain
        /// [`Sign`]-implementing objects (i.e., [`ChannelMonitor`]s and [`ChannelManager`]s).
        /// The bytes are exactly those which `<Self::Signer as Writeable>::write()` writes, and
@@ -502,29 +528,18 @@ pub trait KeysInterface {
        /// [`ChannelMonitor`]: crate::chain::channelmonitor::ChannelMonitor
        /// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager
        fn read_chan_signer(&self, reader: &[u8]) -> Result<Self::Signer, DecodeError>;
-       /// Sign an invoice.
-       /// By parameterizing by the raw invoice bytes instead of the hash, we allow implementors of
-       /// this trait to parse the invoice and make sure they're signing what they expect, rather than
-       /// blindly signing the hash.
-       /// The `hrp` is ASCII bytes, while the invoice data is base32-encoded.
-       ///
-       /// The secret key used to sign the invoice is dependent on the [`Recipient`].
-       ///
-       /// Errors if the [`Recipient`] variant is not supported by the implementation.
-       fn sign_invoice(&self, hrp_bytes: &[u8], invoice_data: &[u5], receipient: Recipient) -> Result<RecoverableSignature, ()>;
-       /// Get secret key material as bytes for use in encrypting and decrypting inbound payment data.
-       ///
-       /// If the implementor of this trait supports [phantom node payments], then every node that is
-       /// intended to be included in the phantom invoice route hints must return the same value from
-       /// this method.
-       // This is because LDK avoids storing inbound payment data by encrypting payment data in the
-       // payment hash and/or payment secret, therefore for a payment to be receivable by multiple
-       // nodes, they must share the key that encrypts this payment data.
+
+       /// Get a script pubkey which we send funds to when claiming on-chain contestable outputs.
        ///
-       /// This method must return the same value each time it is called.
+       /// This method should return a different value each time it is called, to avoid linking
+       /// on-chain funds across channels as controlled to the same user.
+       fn get_destination_script(&self) -> Script;
+
+       /// Get a script pubkey which we will send funds to when closing a channel.
        ///
-       /// [phantom node payments]: PhantomKeysManager
-       fn get_inbound_payment_key_material(&self) -> KeyMaterial;
+       /// This method should return a different value each time it is called, to avoid linking
+       /// on-chain funds across channels as controlled to the same user.
+       fn get_shutdown_scriptpubkey(&self) -> ShutdownScript;
 }
 
 #[derive(Clone)]
@@ -548,8 +563,6 @@ pub struct InMemorySigner {
        pub commitment_seed: [u8; 32],
        /// Holder public keys and basepoints.
        pub(crate) holder_channel_pubkeys: ChannelPublicKeys,
-       /// Private key of our node secret, used for signing channel announcements.
-       node_secret: SecretKey,
        /// Counterparty public keys and counterparty/holder `selected_contest_delay`, populated on channel acceptance.
        channel_parameters: Option<ChannelTransactionParameters>,
        /// The total value of this channel.
@@ -562,7 +575,6 @@ impl InMemorySigner {
        /// Creates a new [`InMemorySigner`].
        pub fn new<C: Signing>(
                secp_ctx: &Secp256k1<C>,
-               node_secret: SecretKey,
                funding_key: SecretKey,
                revocation_base_key: SecretKey,
                payment_key: SecretKey,
@@ -583,7 +595,6 @@ impl InMemorySigner {
                        delayed_payment_base_key,
                        htlc_base_key,
                        commitment_seed,
-                       node_secret,
                        channel_value_satoshis,
                        holder_channel_pubkeys,
                        channel_parameters: None,
@@ -854,10 +865,11 @@ impl BaseSign for InMemorySigner {
                Ok(sign(secp_ctx, &hash_to_message!(&sighash[..]), &self.funding_key))
        }
 
-       fn sign_channel_announcement(&self, msg: &UnsignedChannelAnnouncement, secp_ctx: &Secp256k1<secp256k1::All>)
-       -> Result<(Signature, Signature), ()> {
+       fn sign_channel_announcement_with_funding_key(
+               &self, msg: &UnsignedChannelAnnouncement, secp_ctx: &Secp256k1<secp256k1::All>
+       ) -> Result<Signature, ()> {
                let msghash = hash_to_message!(&Sha256dHash::hash(&msg.encode()[..])[..]);
-               Ok((sign(secp_ctx, &msghash, &self.node_secret), sign(secp_ctx, &msghash, &self.funding_key)))
+               Ok(sign(secp_ctx, &msghash, &self.funding_key))
        }
 
        fn provide_channel_parameters(&mut self, channel_parameters: &ChannelTransactionParameters) {
@@ -897,8 +909,8 @@ impl Writeable for InMemorySigner {
        }
 }
 
-impl ReadableArgs<SecretKey> for InMemorySigner {
-       fn read<R: io::Read>(reader: &mut R, node_secret: SecretKey) -> Result<Self, DecodeError> {
+impl Readable for InMemorySigner {
+       fn read<R: io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
                let _ver = read_ver_prefix!(reader, SERIALIZATION_VERSION);
 
                let funding_key = Readable::read(reader)?;
@@ -923,7 +935,6 @@ impl ReadableArgs<SecretKey> for InMemorySigner {
                        payment_key,
                        delayed_payment_base_key,
                        htlc_base_key,
-                       node_secret,
                        commitment_seed,
                        channel_value_satoshis,
                        holder_channel_pubkeys,
@@ -933,8 +944,8 @@ impl ReadableArgs<SecretKey> for InMemorySigner {
        }
 }
 
-/// Simple [`KeysInterface`] implementation that takes a 32-byte seed for use as a BIP 32 extended
-/// key and derives keys from that.
+/// Simple implementation of [`EntropySource`], [`NodeSigner`], and [`SignerProvider`] that takes a
+/// 32-byte seed for use as a BIP 32 extended key and derives keys from that.
 ///
 /// Your `node_id` is seed/0'.
 /// Unilateral closes may use seed/1'.
@@ -1051,7 +1062,9 @@ impl KeysManager {
                // We only seriously intend to rely on the channel_master_key for true secure
                // entropy, everything else just ensures uniqueness. We rely on the unique_start (ie
                // starting_time provided in the constructor) to be unique.
-               let child_privkey = self.channel_master_key.ckd_priv(&self.secp_ctx, ChildNumber::from_hardened_idx(chan_id as u32).expect("key space exhausted")).expect("Your RNG is busted");
+               let child_privkey = self.channel_master_key.ckd_priv(&self.secp_ctx,
+                               ChildNumber::from_hardened_idx((chan_id as u32) % (1 << 31)).expect("key space exhausted")
+                       ).expect("Your RNG is busted");
                unique_start.input(&child_privkey.private_key[..]);
 
                let seed = Sha256::from_engine(unique_start).into_inner();
@@ -1079,7 +1092,6 @@ impl KeysManager {
 
                InMemorySigner::new(
                        &self.secp_ctx,
-                       self.node_secret,
                        funding_key,
                        revocation_base_key,
                        payment_key,
@@ -1222,16 +1234,20 @@ impl KeysManager {
        }
 }
 
-impl KeysInterface for KeysManager {
-       type Signer = InMemorySigner;
+impl EntropySource for KeysManager {
+       fn get_secure_random_bytes(&self) -> [u8; 32] {
+               let mut sha = self.rand_bytes_unique_start.clone();
 
-       fn get_node_secret(&self, recipient: Recipient) -> Result<SecretKey, ()> {
-               match recipient {
-                       Recipient::Node => Ok(self.node_secret.clone()),
-                       Recipient::PhantomNode => Err(())
-               }
+               let child_ix = self.rand_bytes_child_index.fetch_add(1, Ordering::AcqRel);
+               let child_privkey = self.rand_bytes_master_key.ckd_priv(&self.secp_ctx, ChildNumber::from_hardened_idx(child_ix as u32).expect("key space exhausted")).expect("Your RNG is busted");
+               sha.input(&child_privkey.private_key[..]);
+
+               sha.input(b"Unique Secure Random Bytes Salt");
+               Sha256::from_engine(sha).into_inner()
        }
+}
 
+impl NodeSigner for KeysManager {
        fn get_node_id(&self, recipient: Recipient) -> Result<PublicKey, ()> {
                match recipient {
                        Recipient::Node => Ok(self.node_id.clone()),
@@ -1240,7 +1256,10 @@ impl KeysInterface for KeysManager {
        }
 
        fn ecdh(&self, recipient: Recipient, other_key: &PublicKey, tweak: Option<&Scalar>) -> Result<SharedSecret, ()> {
-               let mut node_secret = self.get_node_secret(recipient)?;
+               let mut node_secret = match recipient {
+                       Recipient::Node => Ok(self.node_secret.clone()),
+                       Recipient::PhantomNode => Err(())
+               }?;
                if let Some(tweak) = tweak {
                        node_secret = node_secret.mul_tweak(tweak).map_err(|_| ())?;
                }
@@ -1251,17 +1270,32 @@ impl KeysInterface for KeysManager {
                self.inbound_payment_key.clone()
        }
 
-       fn get_destination_script(&self) -> Script {
-               self.destination_script.clone()
+       fn sign_invoice(&self, hrp_bytes: &[u8], invoice_data: &[u5], recipient: Recipient) -> Result<RecoverableSignature, ()> {
+               let preimage = construct_invoice_preimage(&hrp_bytes, &invoice_data);
+               let secret = match recipient {
+                       Recipient::Node => Ok(&self.node_secret),
+                       Recipient::PhantomNode => Err(())
+               }?;
+               Ok(self.secp_ctx.sign_ecdsa_recoverable(&hash_to_message!(&Sha256::hash(&preimage)), secret))
        }
 
-       fn get_shutdown_scriptpubkey(&self) -> ShutdownScript {
-               ShutdownScript::new_p2wpkh_from_pubkey(self.shutdown_pubkey.clone())
+       fn sign_gossip_message(&self, msg: UnsignedGossipMessage) -> Result<Signature, ()> {
+               let msg_hash = hash_to_message!(&Sha256dHash::hash(&msg.encode()[..])[..]);
+               Ok(sign(&self.secp_ctx, &msg_hash, &self.node_secret))
        }
+}
+
+impl SignerProvider for KeysManager {
+       type Signer = InMemorySigner;
 
        fn generate_channel_keys_id(&self, _inbound: bool, _channel_value_satoshis: u64, user_channel_id: u128) -> [u8; 32] {
                let child_idx = self.channel_child_index.fetch_add(1, Ordering::AcqRel);
-               assert!(child_idx <= core::u32::MAX as usize);
+               // `child_idx` is the only thing guaranteed to make each channel unique without a restart
+               // (though `user_channel_id` should help, depending on user behavior). If it manages to
+               // roll over, we may generate duplicate keys for two different channels, which could result
+               // in loss of funds. Because we only support 32-bit+ systems, assert that our `AtomicUsize`
+               // doesn't reach `u32::MAX`.
+               assert!(child_idx < core::u32::MAX as usize, "2^32 channels opened without restart");
                let mut id = [0; 32];
                id[0..4].copy_from_slice(&(child_idx as u32).to_be_bytes());
                id[4..8].copy_from_slice(&self.starting_time_nanos.to_be_bytes());
@@ -1274,28 +1308,16 @@ impl KeysInterface for KeysManager {
                self.derive_channel_keys(channel_value_satoshis, &channel_keys_id)
        }
 
-       fn get_secure_random_bytes(&self) -> [u8; 32] {
-               let mut sha = self.rand_bytes_unique_start.clone();
-
-               let child_ix = self.rand_bytes_child_index.fetch_add(1, Ordering::AcqRel);
-               let child_privkey = self.rand_bytes_master_key.ckd_priv(&self.secp_ctx, ChildNumber::from_hardened_idx(child_ix as u32).expect("key space exhausted")).expect("Your RNG is busted");
-               sha.input(&child_privkey.private_key[..]);
-
-               sha.input(b"Unique Secure Random Bytes Salt");
-               Sha256::from_engine(sha).into_inner()
+       fn read_chan_signer(&self, reader: &[u8]) -> Result<Self::Signer, DecodeError> {
+               InMemorySigner::read(&mut io::Cursor::new(reader))
        }
 
-       fn read_chan_signer(&self, reader: &[u8]) -> Result<Self::Signer, DecodeError> {
-               InMemorySigner::read(&mut io::Cursor::new(reader), self.node_secret.clone())
+       fn get_destination_script(&self) -> Script {
+               self.destination_script.clone()
        }
 
-       fn sign_invoice(&self, hrp_bytes: &[u8], invoice_data: &[u5], recipient: Recipient) -> Result<RecoverableSignature, ()> {
-               let preimage = construct_invoice_preimage(&hrp_bytes, &invoice_data);
-               let secret = match recipient {
-                       Recipient::Node => self.get_node_secret(Recipient::Node)?,
-                       Recipient::PhantomNode => return Err(()),
-               };
-               Ok(self.secp_ctx.sign_ecdsa_recoverable(&hash_to_message!(&Sha256::hash(&preimage)), &secret))
+       fn get_shutdown_scriptpubkey(&self) -> ShutdownScript {
+               ShutdownScript::new_p2wpkh_from_pubkey(self.shutdown_pubkey.clone())
        }
 }
 
@@ -1327,16 +1349,13 @@ pub struct PhantomKeysManager {
        phantom_node_id: PublicKey,
 }
 
-impl KeysInterface for PhantomKeysManager {
-       type Signer = InMemorySigner;
-
-       fn get_node_secret(&self, recipient: Recipient) -> Result<SecretKey, ()> {
-               match recipient {
-                       Recipient::Node => self.inner.get_node_secret(Recipient::Node),
-                       Recipient::PhantomNode => Ok(self.phantom_secret.clone()),
-               }
+impl EntropySource for PhantomKeysManager {
+       fn get_secure_random_bytes(&self) -> [u8; 32] {
+               self.inner.get_secure_random_bytes()
        }
+}
 
+impl NodeSigner for PhantomKeysManager {
        fn get_node_id(&self, recipient: Recipient) -> Result<PublicKey, ()> {
                match recipient {
                        Recipient::Node => self.inner.get_node_id(Recipient::Node),
@@ -1345,7 +1364,10 @@ impl KeysInterface for PhantomKeysManager {
        }
 
        fn ecdh(&self, recipient: Recipient, other_key: &PublicKey, tweak: Option<&Scalar>) -> Result<SharedSecret, ()> {
-               let mut node_secret = self.get_node_secret(recipient)?;
+               let mut node_secret = match recipient {
+                       Recipient::Node => self.inner.node_secret.clone(),
+                       Recipient::PhantomNode => self.phantom_secret.clone(),
+               };
                if let Some(tweak) = tweak {
                        node_secret = node_secret.mul_tweak(tweak).map_err(|_| ())?;
                }
@@ -1356,13 +1378,22 @@ impl KeysInterface for PhantomKeysManager {
                self.inbound_payment_key.clone()
        }
 
-       fn get_destination_script(&self) -> Script {
-               self.inner.get_destination_script()
+       fn sign_invoice(&self, hrp_bytes: &[u8], invoice_data: &[u5], recipient: Recipient) -> Result<RecoverableSignature, ()> {
+               let preimage = construct_invoice_preimage(&hrp_bytes, &invoice_data);
+               let secret = match recipient {
+                       Recipient::Node => &self.inner.node_secret,
+                       Recipient::PhantomNode => &self.phantom_secret,
+               };
+               Ok(self.inner.secp_ctx.sign_ecdsa_recoverable(&hash_to_message!(&Sha256::hash(&preimage)), secret))
        }
 
-       fn get_shutdown_scriptpubkey(&self) -> ShutdownScript {
-               self.inner.get_shutdown_scriptpubkey()
+       fn sign_gossip_message(&self, msg: UnsignedGossipMessage) -> Result<Signature, ()> {
+               self.inner.sign_gossip_message(msg)
        }
+}
+
+impl SignerProvider for PhantomKeysManager {
+       type Signer = InMemorySigner;
 
        fn generate_channel_keys_id(&self, inbound: bool, channel_value_satoshis: u64, user_channel_id: u128) -> [u8; 32] {
                self.inner.generate_channel_keys_id(inbound, channel_value_satoshis, user_channel_id)
@@ -1372,18 +1403,16 @@ impl KeysInterface for PhantomKeysManager {
                self.inner.derive_channel_signer(channel_value_satoshis, channel_keys_id)
        }
 
-       fn get_secure_random_bytes(&self) -> [u8; 32] {
-               self.inner.get_secure_random_bytes()
-       }
-
        fn read_chan_signer(&self, reader: &[u8]) -> Result<Self::Signer, DecodeError> {
                self.inner.read_chan_signer(reader)
        }
 
-       fn sign_invoice(&self, hrp_bytes: &[u8], invoice_data: &[u5], recipient: Recipient) -> Result<RecoverableSignature, ()> {
-               let preimage = construct_invoice_preimage(&hrp_bytes, &invoice_data);
-               let secret = self.get_node_secret(recipient)?;
-               Ok(self.inner.secp_ctx.sign_ecdsa_recoverable(&hash_to_message!(&Sha256::hash(&preimage)), &secret))
+       fn get_destination_script(&self) -> Script {
+               self.inner.get_destination_script()
+       }
+
+       fn get_shutdown_scriptpubkey(&self) -> ShutdownScript {
+               self.inner.get_shutdown_scriptpubkey()
        }
 }