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;
/// A trait that can handle cryptographic operations at the scope level of a node.
pub trait NodeSigner {
- /// Get node secret key based on the provided [`Recipient`].
- ///
- /// The `node_id`/`network_key` is the public key that corresponds to this secret key.
- ///
- /// 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 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
/// [phantom node payments]: PhantomKeysManager
fn get_inbound_payment_key_material(&self) -> KeyMaterial;
- /// Get node id based on the provided [`Recipient`]. This public key corresponds to the secret in
- /// [`get_node_secret`].
+ /// 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, ()>;
- /// Gets the ECDH shared secret of our [`node secret`] and `other_key`, multiplying by `tweak` if
+ /// 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, ()>;
/// Sign an invoice.
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.
/// 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,
delayed_payment_base_key,
htlc_base_key,
commitment_seed,
- node_secret,
channel_value_satoshis,
holder_channel_pubkeys,
channel_parameters: None,
}
}
-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)?;
payment_key,
delayed_payment_base_key,
htlc_base_key,
- node_secret,
commitment_seed,
channel_value_satoshis,
holder_channel_pubkeys,
InMemorySigner::new(
&self.secp_ctx,
- self.node_secret,
funding_key,
revocation_base_key,
payment_key,
}
impl NodeSigner for KeysManager {
- fn get_node_secret(&self, recipient: Recipient) -> Result<SecretKey, ()> {
- match recipient {
- Recipient::Node => Ok(self.node_secret.clone()),
- Recipient::PhantomNode => Err(())
- }
- }
-
fn get_node_id(&self, recipient: Recipient) -> Result<PublicKey, ()> {
match recipient {
Recipient::Node => Ok(self.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)?;
+ 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(|_| ())?;
}
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))
+ Recipient::Node => Ok(&self.node_secret),
+ Recipient::PhantomNode => Err(())
+ }?;
+ Ok(self.secp_ctx.sign_ecdsa_recoverable(&hash_to_message!(&Sha256::hash(&preimage)), secret))
}
fn sign_gossip_message(&self, msg: UnsignedGossipMessage) -> Result<Signature, ()> {
}
fn read_chan_signer(&self, reader: &[u8]) -> Result<Self::Signer, DecodeError> {
- InMemorySigner::read(&mut io::Cursor::new(reader), self.node_secret.clone())
+ InMemorySigner::read(&mut io::Cursor::new(reader))
}
fn get_destination_script(&self) -> Script {
}
impl NodeSigner for PhantomKeysManager {
- 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()),
- }
- }
-
fn get_node_id(&self, recipient: Recipient) -> Result<PublicKey, ()> {
match recipient {
Recipient::Node => self.inner.get_node_id(Recipient::Node),
}
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(|_| ())?;
}
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))
+ 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 sign_gossip_message(&self, msg: UnsignedGossipMessage) -> Result<Signature, ()> {