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.
This commit is contained in:
Valentine Wallace 2022-02-09 17:22:53 -05:00
parent f6c75d8ec3
commit adeec71ed8
No known key found for this signature in database
GPG key ID: FD3E106A2CE099B4
7 changed files with 44 additions and 32 deletions

View file

@ -161,8 +161,8 @@ struct KeyProvider {
impl KeysInterface for KeyProvider { impl KeysInterface for KeyProvider {
type Signer = EnforcingSigner; type Signer = EnforcingSigner;
fn get_node_secret(&self) -> SecretKey { fn get_node_secret(&self, _recipient: Recipient) -> Result<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() 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 { 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 id = self.rand_bytes_id.fetch_add(1, atomic::Ordering::Relaxed);
let keys = InMemorySigner::new( let keys = InMemorySigner::new(
&secp_ctx, &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, 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, 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(), 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<Self::Signer, DecodeError> { fn read_chan_signer(&self, buffer: &[u8]) -> Result<Self::Signer, DecodeError> {
let mut reader = std::io::Cursor::new(buffer); 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); let state = self.make_enforcement_state_cell(inner.commitment_seed);
Ok(EnforcingSigner { Ok(EnforcingSigner {

View file

@ -265,8 +265,8 @@ struct KeyProvider {
impl KeysInterface for KeyProvider { impl KeysInterface for KeyProvider {
type Signer = EnforcingSigner; type Signer = EnforcingSigner;
fn get_node_secret(&self) -> SecretKey { fn get_node_secret(&self, _recipient: Recipient) -> Result<SecretKey, ()> {
self.node_secret.clone() Ok(self.node_secret.clone())
} }
fn get_inbound_payment_key_material(&self) -> KeyMaterial { fn get_inbound_payment_key_material(&self) -> KeyMaterial {
@ -390,7 +390,7 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
best_block: BestBlock::from_genesis(network), 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 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 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 net_graph_msg_handler = Arc::new(NetGraphMsgHandler::new(Arc::clone(&network_graph), None, Arc::clone(&logger)));
let scorer = FixedPenaltyScorer::with_penalty(0); let scorer = FixedPenaltyScorer::with_penalty(0);

View file

@ -343,7 +343,7 @@ mod tests {
use bitcoin::network::constants::Network; use bitcoin::network::constants::Network;
use lightning::chain::{BestBlock, Confirm, chainmonitor}; use lightning::chain::{BestBlock, Confirm, chainmonitor};
use lightning::chain::channelmonitor::ANTI_REORG_DELAY; 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::chain::transaction::OutPoint;
use lightning::get_event_msg; use lightning::get_event_msg;
use lightning::ln::channelmanager::{BREAKDOWN_TIMEOUT, ChainParameters, ChannelManager, SimpleArcChannelManager}; 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 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 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 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 }; let node = Node { node: manager, net_graph_msg_handler, peer_manager, chain_monitor, persister, tx_broadcaster, network_graph, logger, best_block };
nodes.push(node); nodes.push(node);
} }

View file

@ -397,10 +397,11 @@ pub trait KeysInterface {
/// A type which implements Sign which will be returned by get_channel_signer. /// A type which implements Sign which will be returned by get_channel_signer.
type Signer : Sign; 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. /// This method must return the same value each time it is called with a given `Recipient`
fn get_node_secret(&self) -> SecretKey; /// parameter.
fn get_node_secret(&self, recipient: Recipient) -> Result<SecretKey, ()>;
/// Get a script pubkey which we send funds to when claiming on-chain contestable outputs. /// 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 /// 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 { impl KeysInterface for KeysManager {
type Signer = InMemorySigner; type Signer = InMemorySigner;
fn get_node_secret(&self) -> SecretKey { fn get_node_secret(&self, recipient: Recipient) -> Result<SecretKey, ()> {
self.node_secret.clone() match recipient {
Recipient::Node => Ok(self.node_secret.clone()),
Recipient::PhantomNode => Err(())
}
} }
fn get_inbound_payment_key_material(&self) -> KeyMaterial { fn get_inbound_payment_key_material(&self) -> KeyMaterial {
@ -1160,13 +1164,13 @@ impl KeysInterface for KeysManager {
} }
fn read_chan_signer(&self, reader: &[u8]) -> Result<Self::Signer, DecodeError> { fn read_chan_signer(&self, reader: &[u8]) -> Result<Self::Signer, DecodeError> {
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<RecoverableSignature, ()> { fn sign_invoice(&self, hrp_bytes: &[u8], invoice_data: &[u5], recipient: Recipient) -> Result<RecoverableSignature, ()> {
let preimage = construct_invoice_preimage(&hrp_bytes, &invoice_data); let preimage = construct_invoice_preimage(&hrp_bytes, &invoice_data);
let secret = match recipient { let secret = match recipient {
Recipient::Node => self.get_node_secret(), Recipient::Node => self.get_node_secret(Recipient::Node)?,
Recipient::PhantomNode => return Err(()), Recipient::PhantomNode => return Err(()),
}; };
Ok(self.secp_ctx.sign_recoverable(&hash_to_message!(&Sha256::hash(&preimage)), &secret)) Ok(self.secp_ctx.sign_recoverable(&hash_to_message!(&Sha256::hash(&preimage)), &secret))
@ -1203,8 +1207,11 @@ pub struct PhantomKeysManager {
impl KeysInterface for PhantomKeysManager { impl KeysInterface for PhantomKeysManager {
type Signer = InMemorySigner; type Signer = InMemorySigner;
fn get_node_secret(&self) -> SecretKey { fn get_node_secret(&self, recipient: Recipient) -> Result<SecretKey, ()> {
self.inner.get_node_secret() 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 { 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<RecoverableSignature, ()> { fn sign_invoice(&self, hrp_bytes: &[u8], invoice_data: &[u5], recipient: Recipient) -> Result<RecoverableSignature, ()> {
let preimage = construct_invoice_preimage(&hrp_bytes, &invoice_data); let preimage = construct_invoice_preimage(&hrp_bytes, &invoice_data);
let secret = match recipient { let secret = self.get_node_secret(recipient)?;
Recipient::Node => self.get_node_secret(),
Recipient::PhantomNode => self.phantom_secret.clone(),
};
Ok(self.inner.secp_ctx.sign_recoverable(&hash_to_message!(&Sha256::hash(&preimage)), &secret)) Ok(self.inner.secp_ctx.sign_recoverable(&hash_to_message!(&Sha256::hash(&preimage)), &secret))
} }
} }

View file

@ -6236,7 +6236,7 @@ mod tests {
impl KeysInterface for Keys { impl KeysInterface for Keys {
type Signer = InMemorySigner; type Signer = InMemorySigner;
fn get_node_secret(&self) -> SecretKey { panic!(); } fn get_node_secret(&self, _recipient: Recipient) -> Result<SecretKey, ()> { panic!(); }
fn get_inbound_payment_key_material(&self) -> KeyMaterial { panic!(); } fn get_inbound_payment_key_material(&self) -> KeyMaterial { panic!(); }
fn get_destination_script(&self) -> Script { fn get_destination_script(&self) -> Script {
let secp_ctx = Secp256k1::signing_only(); let secp_ctx = Secp256k1::signing_only();

View file

@ -48,7 +48,7 @@ use ln::msgs;
use ln::msgs::NetAddress; use ln::msgs::NetAddress;
use ln::onion_utils; use ln::onion_utils;
use ln::msgs::{ChannelMessageHandler, DecodeError, LightningError, MAX_VALUE_MSAT, OptionalField}; 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::config::UserConfig;
use util::events::{EventHandler, EventsProvider, MessageSendEvent, MessageSendEventsProvider, ClosureReason}; use util::events::{EventHandler, EventsProvider, MessageSendEvent, MessageSendEventsProvider, ClosureReason};
use util::{byte_utils, events}; use util::{byte_utils, events};
@ -1679,8 +1679,8 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
pending_inbound_payments: Mutex::new(HashMap::new()), pending_inbound_payments: Mutex::new(HashMap::new()),
pending_outbound_payments: Mutex::new(HashMap::new()), pending_outbound_payments: Mutex::new(HashMap::new()),
our_network_key: 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()), our_network_pubkey: PublicKey::from_secret_key(&secp_ctx, &keys_manager.get_node_secret(Recipient::Node).unwrap()),
secp_ctx, secp_ctx,
inbound_payment_key: expanded_inbound_key, 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); 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 let Some(network_pubkey) = received_network_pubkey {
if network_pubkey != our_network_pubkey { if network_pubkey != our_network_pubkey {
log_error!(args.logger, "Key that was generated does not match the existing key."); 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_inbound_payments: Mutex::new(pending_inbound_payments),
pending_outbound_payments: Mutex::new(pending_outbound_payments.unwrap()), pending_outbound_payments: Mutex::new(pending_outbound_payments.unwrap()),
our_network_key: args.keys_manager.get_node_secret(), our_network_key,
our_network_pubkey, our_network_pubkey,
secp_ctx, secp_ctx,

View file

@ -70,7 +70,7 @@ pub struct OnlyReadsKeysInterface {}
impl keysinterface::KeysInterface for OnlyReadsKeysInterface { impl keysinterface::KeysInterface for OnlyReadsKeysInterface {
type Signer = EnforcingSigner; type Signer = EnforcingSigner;
fn get_node_secret(&self) -> SecretKey { unreachable!(); } fn get_node_secret(&self, _recipient: Recipient) -> Result<SecretKey, ()> { unreachable!(); }
fn get_inbound_payment_key_material(&self) -> KeyMaterial { unreachable!(); } fn get_inbound_payment_key_material(&self) -> KeyMaterial { unreachable!(); }
fn get_destination_script(&self) -> Script { unreachable!(); } fn get_destination_script(&self) -> Script { unreachable!(); }
fn get_shutdown_scriptpubkey(&self) -> ShutdownScript { unreachable!(); } fn get_shutdown_scriptpubkey(&self) -> ShutdownScript { unreachable!(); }
@ -481,8 +481,12 @@ pub struct TestKeysInterface {
impl keysinterface::KeysInterface for TestKeysInterface { impl keysinterface::KeysInterface for TestKeysInterface {
type Signer = EnforcingSigner; type Signer = EnforcingSigner;
fn get_node_secret(&self) -> SecretKey { self.backing.get_node_secret() } fn get_node_secret(&self, recipient: Recipient) -> Result<SecretKey, ()> {
fn get_inbound_payment_key_material(&self) -> keysinterface::KeyMaterial { self.backing.get_inbound_payment_key_material() } 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_destination_script(&self) -> Script { self.backing.get_destination_script() }
fn get_shutdown_scriptpubkey(&self) -> ShutdownScript { fn get_shutdown_scriptpubkey(&self) -> ShutdownScript {
@ -519,7 +523,7 @@ impl keysinterface::KeysInterface for TestKeysInterface {
fn read_chan_signer(&self, buffer: &[u8]) -> Result<Self::Signer, msgs::DecodeError> { fn read_chan_signer(&self, buffer: &[u8]) -> Result<Self::Signer, msgs::DecodeError> {
let mut reader = io::Cursor::new(buffer); 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); let state = self.make_enforcement_state_cell(inner.commitment_seed);
Ok(EnforcingSigner::new_with_revoked( Ok(EnforcingSigner::new_with_revoked(