From adeec71ed886dd8713696bc7a146b2ecc91cb0c2 Mon Sep 17 00:00:00 2001 From: Valentine Wallace Date: Wed, 9 Feb 2022 17:22:53 -0500 Subject: [PATCH] keysinterface: adapt get_node_secret for phantom payments We want LDK to be able to retrieve the phantom secret key when we see that a payment is destined for a phantom node. --- fuzz/src/chanmon_consistency.rs | 8 +++--- fuzz/src/full_stack.rs | 6 ++--- lightning-background-processor/src/lib.rs | 4 +-- lightning/src/chain/keysinterface.rs | 30 +++++++++++++---------- lightning/src/ln/channel.rs | 2 +- lightning/src/ln/channelmanager.rs | 14 +++++++---- lightning/src/util/test_utils.rs | 12 ++++++--- 7 files changed, 44 insertions(+), 32 deletions(-) diff --git a/fuzz/src/chanmon_consistency.rs b/fuzz/src/chanmon_consistency.rs index 2f526c68f..79faba901 100644 --- a/fuzz/src/chanmon_consistency.rs +++ b/fuzz/src/chanmon_consistency.rs @@ -161,8 +161,8 @@ struct KeyProvider { impl KeysInterface for KeyProvider { type Signer = EnforcingSigner; - fn get_node_secret(&self) -> SecretKey { - SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, self.node_id]).unwrap() + fn get_node_secret(&self, _recipient: Recipient) -> Result { + Ok(SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, self.node_id]).unwrap()) } fn get_inbound_payment_key_material(&self) -> KeyMaterial { @@ -188,7 +188,7 @@ impl KeysInterface for KeyProvider { let id = self.rand_bytes_id.fetch_add(1, atomic::Ordering::Relaxed); let keys = InMemorySigner::new( &secp_ctx, - self.get_node_secret(), + self.get_node_secret(Recipient::Node).unwrap(), SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, self.node_id]).unwrap(), SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, self.node_id]).unwrap(), SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, self.node_id]).unwrap(), @@ -212,7 +212,7 @@ impl KeysInterface for KeyProvider { fn read_chan_signer(&self, buffer: &[u8]) -> Result { let mut reader = std::io::Cursor::new(buffer); - let inner: InMemorySigner = ReadableArgs::read(&mut reader, self.get_node_secret())?; + let inner: InMemorySigner = ReadableArgs::read(&mut reader, self.get_node_secret(Recipient::Node).unwrap())?; let state = self.make_enforcement_state_cell(inner.commitment_seed); Ok(EnforcingSigner { diff --git a/fuzz/src/full_stack.rs b/fuzz/src/full_stack.rs index 74aa5f1c6..292188d7e 100644 --- a/fuzz/src/full_stack.rs +++ b/fuzz/src/full_stack.rs @@ -265,8 +265,8 @@ struct KeyProvider { impl KeysInterface for KeyProvider { type Signer = EnforcingSigner; - fn get_node_secret(&self) -> SecretKey { - self.node_secret.clone() + fn get_node_secret(&self, _recipient: Recipient) -> Result { + Ok(self.node_secret.clone()) } fn get_inbound_payment_key_material(&self) -> KeyMaterial { @@ -390,7 +390,7 @@ pub fn do_test(data: &[u8], logger: &Arc) { best_block: BestBlock::from_genesis(network), }; let channelmanager = Arc::new(ChannelManager::new(fee_est.clone(), monitor.clone(), broadcast.clone(), Arc::clone(&logger), keys_manager.clone(), config, params)); - let our_id = PublicKey::from_secret_key(&Secp256k1::signing_only(), &keys_manager.get_node_secret()); + let our_id = PublicKey::from_secret_key(&Secp256k1::signing_only(), &keys_manager.get_node_secret(Recipient::Node).unwrap()); let network_graph = Arc::new(NetworkGraph::new(genesis_block(network).block_hash())); let net_graph_msg_handler = Arc::new(NetGraphMsgHandler::new(Arc::clone(&network_graph), None, Arc::clone(&logger))); let scorer = FixedPenaltyScorer::with_penalty(0); diff --git a/lightning-background-processor/src/lib.rs b/lightning-background-processor/src/lib.rs index 6e5e60e50..8ed0014a7 100644 --- a/lightning-background-processor/src/lib.rs +++ b/lightning-background-processor/src/lib.rs @@ -343,7 +343,7 @@ mod tests { use bitcoin::network::constants::Network; use lightning::chain::{BestBlock, Confirm, chainmonitor}; use lightning::chain::channelmonitor::ANTI_REORG_DELAY; - use lightning::chain::keysinterface::{InMemorySigner, KeysInterface, KeysManager}; + use lightning::chain::keysinterface::{InMemorySigner, Recipient, KeysInterface, KeysManager}; use lightning::chain::transaction::OutPoint; use lightning::get_event_msg; use lightning::ln::channelmanager::{BREAKDOWN_TIMEOUT, ChainParameters, ChannelManager, SimpleArcChannelManager}; @@ -426,7 +426,7 @@ mod tests { let network_graph = Arc::new(NetworkGraph::new(genesis_block.header.block_hash())); let net_graph_msg_handler = Some(Arc::new(NetGraphMsgHandler::new(network_graph.clone(), Some(chain_source.clone()), logger.clone()))); let msg_handler = MessageHandler { chan_handler: Arc::new(test_utils::TestChannelMessageHandler::new()), route_handler: Arc::new(test_utils::TestRoutingMessageHandler::new() )}; - let peer_manager = Arc::new(PeerManager::new(msg_handler, keys_manager.get_node_secret(), &seed, logger.clone(), IgnoringMessageHandler{})); + let peer_manager = Arc::new(PeerManager::new(msg_handler, keys_manager.get_node_secret(Recipient::Node).unwrap(), &seed, logger.clone(), IgnoringMessageHandler{})); let node = Node { node: manager, net_graph_msg_handler, peer_manager, chain_monitor, persister, tx_broadcaster, network_graph, logger, best_block }; nodes.push(node); } diff --git a/lightning/src/chain/keysinterface.rs b/lightning/src/chain/keysinterface.rs index 04537b7a5..1daeec4ef 100644 --- a/lightning/src/chain/keysinterface.rs +++ b/lightning/src/chain/keysinterface.rs @@ -397,10 +397,11 @@ 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 @@ -1122,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 { @@ -1160,13 +1164,13 @@ 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], recipient: Recipient) -> Result { let preimage = construct_invoice_preimage(&hrp_bytes, &invoice_data); let secret = match recipient { - Recipient::Node => self.get_node_secret(), + 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)) @@ -1203,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 { @@ -1233,10 +1240,7 @@ impl KeysInterface for PhantomKeysManager { fn sign_invoice(&self, hrp_bytes: &[u8], invoice_data: &[u5], recipient: Recipient) -> Result { let preimage = construct_invoice_preimage(&hrp_bytes, &invoice_data); - let secret = match recipient { - Recipient::Node => self.get_node_secret(), - Recipient::PhantomNode => self.phantom_secret.clone(), - }; + let secret = self.get_node_secret(recipient)?; Ok(self.inner.secp_ctx.sign_recoverable(&hash_to_message!(&Sha256::hash(&preimage)), &secret)) } } diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index 5ce0df13c..fb9213142 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -6236,7 +6236,7 @@ mod tests { impl KeysInterface for Keys { type Signer = InMemorySigner; - fn get_node_secret(&self) -> SecretKey { panic!(); } + fn get_node_secret(&self, _recipient: Recipient) -> Result { panic!(); } fn get_inbound_payment_key_material(&self) -> KeyMaterial { panic!(); } fn get_destination_script(&self) -> Script { let secp_ctx = Secp256k1::signing_only(); diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index c79076b59..c49a40093 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -48,7 +48,7 @@ use ln::msgs; use ln::msgs::NetAddress; use ln::onion_utils; use ln::msgs::{ChannelMessageHandler, DecodeError, LightningError, MAX_VALUE_MSAT, OptionalField}; -use chain::keysinterface::{Sign, KeysInterface, KeysManager, InMemorySigner}; +use chain::keysinterface::{Sign, KeysInterface, KeysManager, InMemorySigner, Recipient}; use util::config::UserConfig; use util::events::{EventHandler, EventsProvider, MessageSendEvent, MessageSendEventsProvider, ClosureReason}; use util::{byte_utils, events}; @@ -1679,8 +1679,8 @@ impl ChannelMana pending_inbound_payments: Mutex::new(HashMap::new()), pending_outbound_payments: Mutex::new(HashMap::new()), - our_network_key: keys_manager.get_node_secret(), - our_network_pubkey: PublicKey::from_secret_key(&secp_ctx, &keys_manager.get_node_secret()), + our_network_key: keys_manager.get_node_secret(Recipient::Node).unwrap(), + our_network_pubkey: PublicKey::from_secret_key(&secp_ctx, &keys_manager.get_node_secret(Recipient::Node).unwrap()), secp_ctx, inbound_payment_key: expanded_inbound_key, @@ -6575,7 +6575,11 @@ impl<'a, Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> pending_events_read.append(&mut channel_closures); } - let our_network_pubkey = PublicKey::from_secret_key(&secp_ctx, &args.keys_manager.get_node_secret()); + let our_network_key = match args.keys_manager.get_node_secret(Recipient::Node) { + Ok(key) => key, + Err(()) => return Err(DecodeError::InvalidValue) + }; + let our_network_pubkey = PublicKey::from_secret_key(&secp_ctx, &our_network_key); if let Some(network_pubkey) = received_network_pubkey { if network_pubkey != our_network_pubkey { log_error!(args.logger, "Key that was generated does not match the existing key."); @@ -6604,7 +6608,7 @@ impl<'a, Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> pending_inbound_payments: Mutex::new(pending_inbound_payments), pending_outbound_payments: Mutex::new(pending_outbound_payments.unwrap()), - our_network_key: args.keys_manager.get_node_secret(), + our_network_key, our_network_pubkey, secp_ctx, diff --git a/lightning/src/util/test_utils.rs b/lightning/src/util/test_utils.rs index dcfe65278..92ed197f4 100644 --- a/lightning/src/util/test_utils.rs +++ b/lightning/src/util/test_utils.rs @@ -70,7 +70,7 @@ pub struct OnlyReadsKeysInterface {} impl keysinterface::KeysInterface for OnlyReadsKeysInterface { type Signer = EnforcingSigner; - fn get_node_secret(&self) -> SecretKey { unreachable!(); } + fn get_node_secret(&self, _recipient: Recipient) -> Result { unreachable!(); } fn get_inbound_payment_key_material(&self) -> KeyMaterial { unreachable!(); } fn get_destination_script(&self) -> Script { unreachable!(); } fn get_shutdown_scriptpubkey(&self) -> ShutdownScript { unreachable!(); } @@ -481,8 +481,12 @@ pub struct TestKeysInterface { impl keysinterface::KeysInterface for TestKeysInterface { type Signer = EnforcingSigner; - fn get_node_secret(&self) -> SecretKey { self.backing.get_node_secret() } - fn get_inbound_payment_key_material(&self) -> keysinterface::KeyMaterial { self.backing.get_inbound_payment_key_material() } + fn get_node_secret(&self, recipient: Recipient) -> Result { + self.backing.get_node_secret(recipient) + } + fn get_inbound_payment_key_material(&self) -> keysinterface::KeyMaterial { + self.backing.get_inbound_payment_key_material() + } fn get_destination_script(&self) -> Script { self.backing.get_destination_script() } fn get_shutdown_scriptpubkey(&self) -> ShutdownScript { @@ -519,7 +523,7 @@ impl keysinterface::KeysInterface for TestKeysInterface { fn read_chan_signer(&self, buffer: &[u8]) -> Result { let mut reader = io::Cursor::new(buffer); - let inner: InMemorySigner = ReadableArgs::read(&mut reader, self.get_node_secret())?; + let inner: InMemorySigner = ReadableArgs::read(&mut reader, self.get_node_secret(Recipient::Node).unwrap())?; let state = self.make_enforcement_state_cell(inner.commitment_seed); Ok(EnforcingSigner::new_with_revoked( -- 2.39.5