X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fchain%2Fkeysinterface.rs;h=1daeec4ef62354a1fb9f4a5597ad7678a270ffe3;hb=a50e9549b406a0590b7bcb25706891c04d7f47d2;hp=f5ba6bc3e8f7c85a56e7a1aeceb372fc703bb103;hpb=4706c75028abdb0819024c22dc0066de7e4106dd;p=rust-lightning diff --git a/lightning/src/chain/keysinterface.rs b/lightning/src/chain/keysinterface.rs index f5ba6bc3..1daeec4e 100644 --- a/lightning/src/chain/keysinterface.rs +++ b/lightning/src/chain/keysinterface.rs @@ -380,15 +380,28 @@ pub trait BaseSign { pub trait Sign: BaseSign + Writeable + Clone { } +/// Specifies the recipient of an invoice, to indicate to [`KeysInterface::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. + Node, + /// The invoice should be signed with the phantom node secret key. This secret key must be the + /// same for all nodes participating in the [phantom node payment]. + /// + /// [phantom node payment]: PhantomKeysManager + 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 get_channel_signer. type Signer : Sign; - /// Get node secret key (aka node_id or network_key). + /// Get node secret key (aka node_id or network_key) based on the provided [`Recipient`]. /// - /// This method must return the same value each time it is called. - fn get_node_secret(&self) -> SecretKey; + /// This method must return the same value each time it is called with a given `Recipient` + /// parameter. + fn get_node_secret(&self, recipient: Recipient) -> Result; /// Get a script pubkey which we send funds to when claiming on-chain contestable outputs. /// /// This method should return a different value each time it is called, to avoid linking @@ -424,7 +437,9 @@ pub trait KeysInterface { /// 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. - fn sign_invoice(&self, hrp_bytes: &[u8], invoice_data: &[u5]) -> Result; + /// + /// The secret key used to sign the invoice is dependent on the [`Recipient`]. + fn sign_invoice(&self, hrp_bytes: &[u8], invoice_data: &[u5], receipient: Recipient) -> Result; /// Get secret key material as bytes for use in encrypting and decrypting inbound payment data. /// @@ -1108,8 +1123,11 @@ impl KeysManager { impl KeysInterface for KeysManager { type Signer = InMemorySigner; - fn get_node_secret(&self) -> SecretKey { - self.node_secret.clone() + fn get_node_secret(&self, recipient: Recipient) -> Result { + match recipient { + Recipient::Node => Ok(self.node_secret.clone()), + Recipient::PhantomNode => Err(()) + } } fn get_inbound_payment_key_material(&self) -> KeyMaterial { @@ -1146,12 +1164,16 @@ impl KeysInterface for KeysManager { } fn read_chan_signer(&self, reader: &[u8]) -> Result { - InMemorySigner::read(&mut io::Cursor::new(reader), self.get_node_secret()) + InMemorySigner::read(&mut io::Cursor::new(reader), self.node_secret.clone()) } - fn sign_invoice(&self, hrp_bytes: &[u8], invoice_data: &[u5]) -> Result { + fn sign_invoice(&self, hrp_bytes: &[u8], invoice_data: &[u5], recipient: Recipient) -> Result { let preimage = construct_invoice_preimage(&hrp_bytes, &invoice_data); - Ok(self.secp_ctx.sign_recoverable(&hash_to_message!(&Sha256::hash(&preimage)), &self.get_node_secret())) + let secret = match recipient { + Recipient::Node => self.get_node_secret(Recipient::Node)?, + Recipient::PhantomNode => return Err(()), + }; + Ok(self.secp_ctx.sign_recoverable(&hash_to_message!(&Sha256::hash(&preimage)), &secret)) } } @@ -1185,8 +1207,11 @@ pub struct PhantomKeysManager { impl KeysInterface for PhantomKeysManager { type Signer = InMemorySigner; - fn get_node_secret(&self) -> SecretKey { - self.inner.get_node_secret() + fn get_node_secret(&self, recipient: Recipient) -> Result { + match recipient { + Recipient::Node => self.inner.get_node_secret(Recipient::Node), + Recipient::PhantomNode => Ok(self.phantom_secret.clone()), + } } fn get_inbound_payment_key_material(&self) -> KeyMaterial { @@ -1213,9 +1238,10 @@ impl KeysInterface for PhantomKeysManager { self.inner.read_chan_signer(reader) } - fn sign_invoice(&self, hrp_bytes: &[u8], invoice_data: &[u5]) -> Result { + fn sign_invoice(&self, hrp_bytes: &[u8], invoice_data: &[u5], recipient: Recipient) -> Result { let preimage = construct_invoice_preimage(&hrp_bytes, &invoice_data); - Ok(self.inner.secp_ctx.sign_recoverable(&hash_to_message!(&Sha256::hash(&preimage)), &self.get_node_secret())) + let secret = self.get_node_secret(recipient)?; + Ok(self.inner.secp_ctx.sign_recoverable(&hash_to_message!(&Sha256::hash(&preimage)), &secret)) } }