Merge pull request #1779 from valentinewallace/2022-10-node-pk-keysinterface
authorMatt Corallo <649246+TheBlueMatt@users.noreply.github.com>
Mon, 24 Oct 2022 17:37:25 +0000 (17:37 +0000)
committerGitHub <noreply@github.com>
Mon, 24 Oct 2022 17:37:25 +0000 (17:37 +0000)
Add `KeysInterface::get_node_id` method

1  2 
lightning/src/chain/keysinterface.rs
lightning/src/util/test_utils.rs

index 7650d4f5210cb706af297efc3f8e5303a2b93ed9,6e13d7a09056ba02b91d8f011420d2f47a5643e9..e3108fd54daa9c5a773cf0acfa85611c3c5fd787
@@@ -31,22 -31,22 +31,22 @@@ use bitcoin::secp256k1::ecdh::SharedSec
  use bitcoin::secp256k1::ecdsa::RecoverableSignature;
  use bitcoin::{PackedLockTime, secp256k1, Sequence, Witness};
  
 -use util::{byte_utils, transaction_utils};
 -use util::crypto::{hkdf_extract_expand_twice, sign};
 -use util::ser::{Writeable, Writer, Readable, ReadableArgs};
 -
 -use chain::transaction::OutPoint;
 -use ln::channel::ANCHOR_OUTPUT_VALUE_SATOSHI;
 -use ln::{chan_utils, PaymentPreimage};
 -use ln::chan_utils::{HTLCOutputInCommitment, make_funding_redeemscript, ChannelPublicKeys, HolderCommitmentTransaction, ChannelTransactionParameters, CommitmentTransaction, ClosingTransaction};
 -use ln::msgs::UnsignedChannelAnnouncement;
 -use ln::script::ShutdownScript;
 -
 -use prelude::*;
 +use crate::util::{byte_utils, transaction_utils};
 +use crate::util::crypto::{hkdf_extract_expand_twice, sign};
 +use crate::util::ser::{Writeable, Writer, Readable, ReadableArgs};
 +
 +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::script::ShutdownScript;
 +
 +use crate::prelude::*;
  use core::sync::atomic::{AtomicUsize, Ordering};
 -use io::{self, Error};
 -use ln::msgs::{DecodeError, MAX_VALUE_MSAT};
 -use util::invoice::construct_invoice_preimage;
 +use crate::io::{self, Error};
 +use crate::ln::msgs::{DecodeError, MAX_VALUE_MSAT};
 +use crate::util::invoice::construct_invoice_preimage;
  
  /// Used as initial key material, to be expanded into multiple secret keys (but not to be used
  /// directly). This is used within LDK to encrypt/decrypt inbound payment data.
@@@ -411,11 -411,28 +411,28 @@@ pub trait KeysInterface 
        ///
        /// 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.
        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`].
+       ///
+       /// 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`]: KeysInterface::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
        /// 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.
+       ///
        /// [`node secret`]: Self::get_node_secret
        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.
        /// The hrp is 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], receipient: Recipient) -> Result<RecoverableSignature, ()>;
  
        /// Get secret key material as bytes for use in encrypting and decrypting inbound payment data.
@@@ -871,6 -890,7 +890,7 @@@ impl ReadableArgs<SecretKey> for InMemo
  pub struct KeysManager {
        secp_ctx: Secp256k1<secp256k1::All>,
        node_secret: SecretKey,
+       node_id: PublicKey,
        inbound_payment_key: KeyMaterial,
        destination_script: Script,
        shutdown_pubkey: PublicKey,
@@@ -912,6 -932,7 +932,7 @@@ impl KeysManager 
                match ExtendedPrivKey::new_master(Network::Testnet, seed) {
                        Ok(master_key) => {
                                let node_secret = master_key.ckd_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()) {
                                        Ok(destination_key) => {
                                                let wpubkey_hash = WPubkeyHash::hash(&ExtendedPubKey::from_priv(&secp_ctx, &destination_key).to_pub().to_bytes());
                                let mut res = KeysManager {
                                        secp_ctx,
                                        node_secret,
+                                       node_id,
                                        inbound_payment_key: KeyMaterial(inbound_pmt_key_bytes),
  
                                        destination_script,
@@@ -1158,6 -1180,13 +1180,13 @@@ impl KeysInterface for KeysManager 
                }
        }
  
+       fn get_node_id(&self, recipient: Recipient) -> Result<PublicKey, ()> {
+               match recipient {
+                       Recipient::Node => Ok(self.node_id.clone()),
+                       Recipient::PhantomNode => Err(())
+               }
+       }
        fn ecdh(&self, recipient: Recipient, other_key: &PublicKey, tweak: Option<&Scalar>) -> Result<SharedSecret, ()> {
                let mut node_secret = self.get_node_secret(recipient)?;
                if let Some(tweak) = tweak {
@@@ -1238,6 -1267,7 +1267,7 @@@ pub struct PhantomKeysManager 
        inner: KeysManager,
        inbound_payment_key: KeyMaterial,
        phantom_secret: SecretKey,
+       phantom_node_id: PublicKey,
  }
  
  impl KeysInterface for PhantomKeysManager {
                }
        }
  
+       fn get_node_id(&self, recipient: Recipient) -> Result<PublicKey, ()> {
+               match recipient {
+                       Recipient::Node => self.inner.get_node_id(Recipient::Node),
+                       Recipient::PhantomNode => Ok(self.phantom_node_id.clone()),
+               }
+       }
        fn ecdh(&self, recipient: Recipient, other_key: &PublicKey, tweak: Option<&Scalar>) -> Result<SharedSecret, ()> {
                let mut node_secret = self.get_node_secret(recipient)?;
                if let Some(tweak) = tweak {
@@@ -1303,10 -1340,13 +1340,13 @@@ impl PhantomKeysManager 
        pub fn new(seed: &[u8; 32], starting_time_secs: u64, starting_time_nanos: u32, cross_node_seed: &[u8; 32]) -> Self {
                let inner = KeysManager::new(seed, starting_time_secs, starting_time_nanos);
                let (inbound_key, phantom_key) = hkdf_extract_expand_twice(b"LDK Inbound and Phantom Payment Key Expansion", cross_node_seed);
+               let phantom_secret = SecretKey::from_slice(&phantom_key).unwrap();
+               let phantom_node_id = PublicKey::from_secret_key(&inner.secp_ctx, &phantom_secret);
                Self {
                        inner,
                        inbound_payment_key: KeyMaterial(inbound_key),
-                       phantom_secret: SecretKey::from_slice(&phantom_key).unwrap(),
+                       phantom_secret,
+                       phantom_node_id,
                }
        }
  
index 37302b1e0ec1b6618c580fd7c7bb72b4022d9aad,a7f7fddc310491d99f4285b72894e649b3a6c577..89bf27de2805ef8c152279cc02855d114d7a4e9b
@@@ -7,25 -7,25 +7,25 @@@
  // You may not use this file except in accordance with one or both of these
  // licenses.
  
 -use chain;
 -use chain::WatchedOutput;
 -use chain::chaininterface;
 -use chain::chaininterface::ConfirmationTarget;
 -use chain::chainmonitor;
 -use chain::chainmonitor::MonitorUpdateId;
 -use chain::channelmonitor;
 -use chain::channelmonitor::MonitorEvent;
 -use chain::transaction::OutPoint;
 -use chain::keysinterface;
 -use ln::channelmanager;
 -use ln::features::{ChannelFeatures, InitFeatures, NodeFeatures};
 -use ln::{msgs, wire};
 -use ln::script::ShutdownScript;
 -use routing::scoring::FixedPenaltyScorer;
 -use util::enforcing_trait_impls::{EnforcingSigner, EnforcementState};
 -use util::events;
 -use util::logger::{Logger, Level, Record};
 -use util::ser::{Readable, ReadableArgs, Writer, Writeable};
 +use crate::chain;
 +use crate::chain::WatchedOutput;
 +use crate::chain::chaininterface;
 +use crate::chain::chaininterface::ConfirmationTarget;
 +use crate::chain::chainmonitor;
 +use crate::chain::chainmonitor::MonitorUpdateId;
 +use crate::chain::channelmonitor;
 +use crate::chain::channelmonitor::MonitorEvent;
 +use crate::chain::transaction::OutPoint;
 +use crate::chain::keysinterface;
 +use crate::ln::channelmanager;
 +use crate::ln::features::{ChannelFeatures, InitFeatures, NodeFeatures};
 +use crate::ln::{msgs, wire};
 +use crate::ln::script::ShutdownScript;
 +use crate::routing::scoring::FixedPenaltyScorer;
 +use crate::util::enforcing_trait_impls::{EnforcingSigner, EnforcementState};
 +use crate::util::events;
 +use crate::util::logger::{Logger, Level, Record};
 +use crate::util::ser::{Readable, ReadableArgs, Writer, Writeable};
  
  use bitcoin::blockdata::constants::genesis_block;
  use bitcoin::blockdata::transaction::{Transaction, TxOut};
@@@ -41,14 -41,14 +41,14 @@@ use bitcoin::secp256k1::ecdsa::Recovera
  
  use regex;
  
 -use io;
 -use prelude::*;
 +use crate::io;
 +use crate::prelude::*;
  use core::time::Duration;
 -use sync::{Mutex, Arc};
 +use crate::sync::{Mutex, Arc};
  use core::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
  use core::mem;
  use bitcoin::bech32::u5;
 -use chain::keysinterface::{InMemorySigner, Recipient, KeyMaterial};
 +use crate::chain::keysinterface::{InMemorySigner, Recipient, KeyMaterial};
  
  #[cfg(feature = "std")]
  use std::time::{SystemTime, UNIX_EPOCH};
@@@ -608,6 -608,9 +608,9 @@@ impl keysinterface::KeysInterface for T
        fn get_node_secret(&self, recipient: Recipient) -> Result<SecretKey, ()> {
                self.backing.get_node_secret(recipient)
        }
+       fn get_node_id(&self, recipient: Recipient) -> Result<PublicKey, ()> {
+               self.backing.get_node_id(recipient)
+       }
        fn ecdh(&self, recipient: Recipient, other_key: &PublicKey, tweak: Option<&Scalar>) -> Result<SharedSecret, ()> {
                self.backing.ecdh(recipient, other_key, tweak)
        }