]> git.bitcoin.ninja Git - rust-lightning/commitdiff
Sign gossip messages with NodeSigner
authorWilmer Paulino <wilmer.paulino@gmail.com>
Wed, 18 Jan 2023 21:03:20 +0000 (13:03 -0800)
committerWilmer Paulino <wilmer.paulino@gmail.com>
Thu, 19 Jan 2023 01:23:22 +0000 (17:23 -0800)
fuzz/src/full_stack.rs
lightning-background-processor/src/lib.rs
lightning-net-tokio/src/lib.rs
lightning/src/chain/keysinterface.rs
lightning/src/ln/channel.rs
lightning/src/ln/channelmanager.rs
lightning/src/ln/peer_handler.rs
lightning/src/ln/priv_short_conf_tests.rs
lightning/src/util/enforcing_trait_impls.rs
lightning/src/util/test_utils.rs

index 20a6e55ccce81668a92522710bd78fa38250d6fd..dd1f9f8cf6bad32541986d3f11500d7677a918f8 100644 (file)
@@ -183,7 +183,7 @@ impl<'a> std::hash::Hash for Peer<'a> {
 type ChannelMan<'a> = ChannelManager<
        Arc<chainmonitor::ChainMonitor<EnforcingSigner, Arc<dyn chain::Filter>, Arc<TestBroadcaster>, Arc<FuzzEstimator>, Arc<dyn Logger>, Arc<TestPersister>>>,
        Arc<TestBroadcaster>, Arc<KeyProvider>, Arc<KeyProvider>, Arc<KeyProvider>, Arc<FuzzEstimator>, &'a FuzzRouter, Arc<dyn Logger>>;
-type PeerMan<'a> = PeerManager<Peer<'a>, Arc<ChannelMan<'a>>, Arc<P2PGossipSync<Arc<NetworkGraph<Arc<dyn Logger>>>, Arc<dyn chain::Access>, Arc<dyn Logger>>>, IgnoringMessageHandler, Arc<dyn Logger>, IgnoringMessageHandler>;
+type PeerMan<'a> = PeerManager<Peer<'a>, Arc<ChannelMan<'a>>, Arc<P2PGossipSync<Arc<NetworkGraph<Arc<dyn Logger>>>, Arc<dyn chain::Access>, Arc<dyn Logger>>>, IgnoringMessageHandler, Arc<dyn Logger>, IgnoringMessageHandler, Arc<KeyProvider>>;
 
 struct MoneyLossDetector<'a> {
        manager: Arc<ChannelMan<'a>>,
@@ -462,7 +462,7 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
                chan_handler: channelmanager.clone(),
                route_handler: gossip_sync.clone(),
                onion_message_handler: IgnoringMessageHandler {},
-       }, our_network_key, 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, 0, 15, 0], Arc::clone(&logger), IgnoringMessageHandler{}));
+       }, our_network_key, 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, 0, 15, 0], Arc::clone(&logger), IgnoringMessageHandler{}, keys_manager.clone()));
 
        let mut should_forward = false;
        let mut payments_received: Vec<PaymentHash> = Vec::new();
index 4759c272dc758e2a4bbdaf097fcdc895a2fa01f2..eaee264049a3c278c5f795ff39c4ee6c476f068d 100644 (file)
@@ -385,7 +385,7 @@ pub async fn process_events_async<
        PGS: 'static + Deref<Target = P2PGossipSync<G, CA, L>> + Send + Sync,
        RGS: 'static + Deref<Target = RapidGossipSync<G, L>> + Send,
        UMH: 'static + Deref + Send + Sync,
-       PM: 'static + Deref<Target = PeerManager<Descriptor, CMH, RMH, OMH, L, UMH>> + Send + Sync,
+       PM: 'static + Deref<Target = PeerManager<Descriptor, CMH, RMH, OMH, L, UMH, NS>> + Send + Sync,
        S: 'static + Deref<Target = SC> + Send + Sync,
        SC: WriteableScore<'a>,
        SleepFuture: core::future::Future<Output = bool> + core::marker::Unpin,
@@ -514,7 +514,7 @@ impl BackgroundProcessor {
                PGS: 'static + Deref<Target = P2PGossipSync<G, CA, L>> + Send + Sync,
                RGS: 'static + Deref<Target = RapidGossipSync<G, L>> + Send,
                UMH: 'static + Deref + Send + Sync,
-               PM: 'static + Deref<Target = PeerManager<Descriptor, CMH, RMH, OMH, L, UMH>> + Send + Sync,
+               PM: 'static + Deref<Target = PeerManager<Descriptor, CMH, RMH, OMH, L, UMH, NS>> + Send + Sync,
                S: 'static + Deref<Target = SC> + Send + Sync,
                SC: WriteableScore<'a>,
        >(
@@ -663,7 +663,7 @@ mod tests {
                node: Arc<SimpleArcChannelManager<ChainMonitor, test_utils::TestBroadcaster, test_utils::TestFeeEstimator, test_utils::TestLogger>>,
                p2p_gossip_sync: PGS,
                rapid_gossip_sync: RGS,
-               peer_manager: Arc<PeerManager<TestDescriptor, Arc<test_utils::TestChannelMessageHandler>, Arc<test_utils::TestRoutingMessageHandler>, IgnoringMessageHandler, Arc<test_utils::TestLogger>, IgnoringMessageHandler>>,
+               peer_manager: Arc<PeerManager<TestDescriptor, Arc<test_utils::TestChannelMessageHandler>, Arc<test_utils::TestRoutingMessageHandler>, IgnoringMessageHandler, Arc<test_utils::TestLogger>, IgnoringMessageHandler, Arc<KeysManager>>>,
                chain_monitor: Arc<ChainMonitor>,
                persister: Arc<FilesystemPersister>,
                tx_broadcaster: Arc<test_utils::TestBroadcaster>,
@@ -786,7 +786,7 @@ mod tests {
                        let p2p_gossip_sync = Arc::new(P2PGossipSync::new(network_graph.clone(), Some(chain_source.clone()), logger.clone()));
                        let rapid_gossip_sync = Arc::new(RapidGossipSync::new(network_graph.clone()));
                        let msg_handler = MessageHandler { chan_handler: Arc::new(test_utils::TestChannelMessageHandler::new()), route_handler: Arc::new(test_utils::TestRoutingMessageHandler::new()), onion_message_handler: IgnoringMessageHandler{}};
-                       let peer_manager = Arc::new(PeerManager::new(msg_handler, keys_manager.get_node_secret(Recipient::Node).unwrap(), 0, &seed, logger.clone(), IgnoringMessageHandler{}));
+                       let peer_manager = Arc::new(PeerManager::new(msg_handler, keys_manager.get_node_secret(Recipient::Node).unwrap(), 0, &seed, logger.clone(), IgnoringMessageHandler{}, keys_manager.clone()));
                        let node = Node { node: manager, p2p_gossip_sync, rapid_gossip_sync, peer_manager, chain_monitor, persister, tx_broadcaster, network_graph, logger, best_block, scorer };
                        nodes.push(node);
                }
index 45fe9b12f61b17a7b078805de1e6344efa91fbf3..c979a3e70479179ecdb5882743e13f86ba300bb8 100644 (file)
@@ -32,6 +32,7 @@
 //! type TxBroadcaster = dyn lightning::chain::chaininterface::BroadcasterInterface + Send + Sync;
 //! type FeeEstimator = dyn lightning::chain::chaininterface::FeeEstimator + Send + Sync;
 //! type Logger = dyn lightning::util::logger::Logger + Send + Sync;
+//! type NodeSigner = dyn lightning::chain::keysinterface::NodeSigner + Send + Sync;
 //! type ChainAccess = dyn lightning::chain::Access + Send + Sync;
 //! type ChainFilter = dyn lightning::chain::Filter + Send + Sync;
 //! type DataPersister = dyn lightning::chain::chainmonitor::Persist<lightning::chain::keysinterface::InMemorySigner> + Send + Sync;
@@ -80,6 +81,7 @@ use tokio::{io, time};
 use tokio::sync::mpsc;
 use tokio::io::{AsyncReadExt, AsyncWrite, AsyncWriteExt};
 
+use lightning::chain::keysinterface::NodeSigner;
 use lightning::ln::peer_handler;
 use lightning::ln::peer_handler::SocketDescriptor as LnSocketTrait;
 use lightning::ln::peer_handler::CustomMessageHandler;
@@ -123,21 +125,23 @@ struct Connection {
        id: u64,
 }
 impl Connection {
-       async fn poll_event_process<PM, CMH, RMH, OMH, L, UMH>(
+       async fn poll_event_process<PM, CMH, RMH, OMH, L, UMH, NS>(
                peer_manager: PM,
                mut event_receiver: mpsc::Receiver<()>,
        ) where
-                       PM: Deref<Target = peer_handler::PeerManager<SocketDescriptor, CMH, RMH, OMH, L, UMH>> + 'static + Send + Sync,
+                       PM: Deref<Target = peer_handler::PeerManager<SocketDescriptor, CMH, RMH, OMH, L, UMH, NS>> + 'static + Send + Sync,
                        CMH: Deref + 'static + Send + Sync,
                        RMH: Deref + 'static + Send + Sync,
                        OMH: Deref + 'static + Send + Sync,
                        L: Deref + 'static + Send + Sync,
                        UMH: Deref + 'static + Send + Sync,
+                       NS: Deref + 'static + Send + Sync,
                        CMH::Target: ChannelMessageHandler + Send + Sync,
                        RMH::Target: RoutingMessageHandler + Send + Sync,
                        OMH::Target: OnionMessageHandler + Send + Sync,
                        L::Target: Logger + Send + Sync,
                        UMH::Target: CustomMessageHandler + Send + Sync,
+                       NS::Target: NodeSigner + Send + Sync,
        {
                loop {
                        if event_receiver.recv().await.is_none() {
@@ -147,24 +151,26 @@ impl Connection {
                }
        }
 
-       async fn schedule_read<PM, CMH, RMH, OMH, L, UMH>(
+       async fn schedule_read<PM, CMH, RMH, OMH, L, UMH, NS>(
                peer_manager: PM,
                us: Arc<Mutex<Self>>,
                mut reader: io::ReadHalf<TcpStream>,
                mut read_wake_receiver: mpsc::Receiver<()>,
                mut write_avail_receiver: mpsc::Receiver<()>,
        ) where
-                       PM: Deref<Target = peer_handler::PeerManager<SocketDescriptor, CMH, RMH, OMH, L, UMH>> + 'static + Send + Sync + Clone,
+                       PM: Deref<Target = peer_handler::PeerManager<SocketDescriptor, CMH, RMH, OMH, L, UMH, NS>> + 'static + Send + Sync + Clone,
                        CMH: Deref + 'static + Send + Sync,
                        RMH: Deref + 'static + Send + Sync,
                        OMH: Deref + 'static + Send + Sync,
                        L: Deref + 'static + Send + Sync,
                        UMH: Deref + 'static + Send + Sync,
+                       NS: Deref + 'static + Send + Sync,
                        CMH::Target: ChannelMessageHandler + 'static + Send + Sync,
                        RMH::Target: RoutingMessageHandler + 'static + Send + Sync,
                        OMH::Target: OnionMessageHandler + 'static + Send + Sync,
                        L::Target: Logger + 'static + Send + Sync,
                        UMH::Target: CustomMessageHandler + 'static + Send + Sync,
+                       NS::Target: NodeSigner + 'static + Send + Sync,
                {
                // Create a waker to wake up poll_event_process, above
                let (event_waker, event_receiver) = mpsc::channel(1);
@@ -283,21 +289,23 @@ fn get_addr_from_stream(stream: &StdTcpStream) -> Option<NetAddress> {
 /// The returned future will complete when the peer is disconnected and associated handling
 /// futures are freed, though, because all processing futures are spawned with tokio::spawn, you do
 /// not need to poll the provided future in order to make progress.
-pub fn setup_inbound<PM, CMH, RMH, OMH, L, UMH>(
+pub fn setup_inbound<PM, CMH, RMH, OMH, L, UMH, NS>(
        peer_manager: PM,
        stream: StdTcpStream,
 ) -> impl std::future::Future<Output=()> where
-               PM: Deref<Target = peer_handler::PeerManager<SocketDescriptor, CMH, RMH, OMH, L, UMH>> + 'static + Send + Sync + Clone,
+               PM: Deref<Target = peer_handler::PeerManager<SocketDescriptor, CMH, RMH, OMH, L, UMH, NS>> + 'static + Send + Sync + Clone,
                CMH: Deref + 'static + Send + Sync,
                RMH: Deref + 'static + Send + Sync,
                OMH: Deref + 'static + Send + Sync,
                L: Deref + 'static + Send + Sync,
                UMH: Deref + 'static + Send + Sync,
+               NS: Deref + 'static + Send + Sync,
                CMH::Target: ChannelMessageHandler + Send + Sync,
                RMH::Target: RoutingMessageHandler + Send + Sync,
                OMH::Target: OnionMessageHandler + Send + Sync,
                L::Target: Logger + Send + Sync,
                UMH::Target: CustomMessageHandler + Send + Sync,
+               NS::Target: NodeSigner + Send + Sync,
 {
        let remote_addr = get_addr_from_stream(&stream);
        let (reader, write_receiver, read_receiver, us) = Connection::new(stream);
@@ -336,22 +344,24 @@ pub fn setup_inbound<PM, CMH, RMH, OMH, L, UMH>(
 /// The returned future will complete when the peer is disconnected and associated handling
 /// futures are freed, though, because all processing futures are spawned with tokio::spawn, you do
 /// not need to poll the provided future in order to make progress.
-pub fn setup_outbound<PM, CMH, RMH, OMH, L, UMH>(
+pub fn setup_outbound<PM, CMH, RMH, OMH, L, UMH, NS>(
        peer_manager: PM,
        their_node_id: PublicKey,
        stream: StdTcpStream,
 ) -> impl std::future::Future<Output=()> where
-               PM: Deref<Target = peer_handler::PeerManager<SocketDescriptor, CMH, RMH, OMH, L, UMH>> + 'static + Send + Sync + Clone,
+               PM: Deref<Target = peer_handler::PeerManager<SocketDescriptor, CMH, RMH, OMH, L, UMH, NS>> + 'static + Send + Sync + Clone,
                CMH: Deref + 'static + Send + Sync,
                RMH: Deref + 'static + Send + Sync,
                OMH: Deref + 'static + Send + Sync,
                L: Deref + 'static + Send + Sync,
                UMH: Deref + 'static + Send + Sync,
+               NS: Deref + 'static + Send + Sync,
                CMH::Target: ChannelMessageHandler + Send + Sync,
                RMH::Target: RoutingMessageHandler + Send + Sync,
                OMH::Target: OnionMessageHandler + Send + Sync,
                L::Target: Logger + Send + Sync,
                UMH::Target: CustomMessageHandler + Send + Sync,
+               NS::Target: NodeSigner + Send + Sync,
 {
        let remote_addr = get_addr_from_stream(&stream);
        let (reader, mut write_receiver, read_receiver, us) = Connection::new(stream);
@@ -419,22 +429,24 @@ pub fn setup_outbound<PM, CMH, RMH, OMH, L, UMH>(
 /// disconnected and associated handling futures are freed, though, because all processing in said
 /// futures are spawned with tokio::spawn, you do not need to poll the second future in order to
 /// make progress.
-pub async fn connect_outbound<PM, CMH, RMH, OMH, L, UMH>(
+pub async fn connect_outbound<PM, CMH, RMH, OMH, L, UMH, NS>(
        peer_manager: PM,
        their_node_id: PublicKey,
        addr: SocketAddr,
 ) -> Option<impl std::future::Future<Output=()>> where
-               PM: Deref<Target = peer_handler::PeerManager<SocketDescriptor, CMH, RMH, OMH, L, UMH>> + 'static + Send + Sync + Clone,
+               PM: Deref<Target = peer_handler::PeerManager<SocketDescriptor, CMH, RMH, OMH, L, UMH, NS>> + 'static + Send + Sync + Clone,
                CMH: Deref + 'static + Send + Sync,
                RMH: Deref + 'static + Send + Sync,
                OMH: Deref + 'static + Send + Sync,
                L: Deref + 'static + Send + Sync,
                UMH: Deref + 'static + Send + Sync,
+               NS: Deref + 'static + Send + Sync,
                CMH::Target: ChannelMessageHandler + Send + Sync,
                RMH::Target: RoutingMessageHandler + Send + Sync,
                OMH::Target: OnionMessageHandler + Send + Sync,
                L::Target: Logger + Send + Sync,
                UMH::Target: CustomMessageHandler + Send + Sync,
+               NS::Target: NodeSigner + Send + Sync,
 {
        if let Ok(Ok(stream)) = time::timeout(Duration::from_secs(10), async { TcpStream::connect(&addr).await.map(|s| s.into_std().unwrap()) }).await {
                Some(setup_outbound(peer_manager, their_node_id, stream))
@@ -573,6 +585,7 @@ mod tests {
        use lightning::ln::peer_handler::{MessageHandler, PeerManager};
        use lightning::ln::features::NodeFeatures;
        use lightning::util::events::*;
+       use lightning::util::test_utils::TestNodeSigner;
        use bitcoin::secp256k1::{Secp256k1, SecretKey, PublicKey};
 
        use tokio::sync::mpsc;
@@ -688,7 +701,7 @@ mod tests {
                        chan_handler: Arc::clone(&a_handler),
                        route_handler: Arc::clone(&a_handler),
                        onion_message_handler: Arc::new(lightning::ln::peer_handler::IgnoringMessageHandler{}),
-               }, a_key.clone(), 0, &[1; 32], Arc::new(TestLogger()), Arc::new(lightning::ln::peer_handler::IgnoringMessageHandler{})));
+               }, a_key.clone(), 0, &[1; 32], Arc::new(TestLogger()), Arc::new(lightning::ln::peer_handler::IgnoringMessageHandler{}), Arc::new(TestNodeSigner::new(a_key))));
 
                let (b_connected_sender, mut b_connected) = mpsc::channel(1);
                let (b_disconnected_sender, mut b_disconnected) = mpsc::channel(1);
@@ -703,7 +716,7 @@ mod tests {
                        chan_handler: Arc::clone(&b_handler),
                        route_handler: Arc::clone(&b_handler),
                        onion_message_handler: Arc::new(lightning::ln::peer_handler::IgnoringMessageHandler{}),
-               }, b_key.clone(), 0, &[2; 32], Arc::new(TestLogger()), Arc::new(lightning::ln::peer_handler::IgnoringMessageHandler{})));
+               }, b_key.clone(), 0, &[2; 32], Arc::new(TestLogger()), Arc::new(lightning::ln::peer_handler::IgnoringMessageHandler{}), Arc::new(TestNodeSigner::new(b_key))));
 
                // We bind on localhost, hoping the environment is properly configured with a local
                // address. This may not always be the case in containers and the like, so if this test is
@@ -756,7 +769,7 @@ mod tests {
                        chan_handler: Arc::new(lightning::ln::peer_handler::ErroringMessageHandler::new()),
                        onion_message_handler: Arc::new(lightning::ln::peer_handler::IgnoringMessageHandler{}),
                        route_handler: Arc::new(lightning::ln::peer_handler::IgnoringMessageHandler{}),
-               }, a_key, 0, &[1; 32], Arc::new(TestLogger()), Arc::new(lightning::ln::peer_handler::IgnoringMessageHandler{})));
+               }, a_key, 0, &[1; 32], Arc::new(TestLogger()), Arc::new(lightning::ln::peer_handler::IgnoringMessageHandler{}), Arc::new(TestNodeSigner::new(a_key))));
 
                // Make two connections, one for an inbound and one for an outbound connection
                let conn_a = {
index 83243ee88d57dc7c966cbc77549d281e54f9f62f..cb7b1729225446efb68497661d0a798183ede57d 100644 (file)
@@ -383,17 +383,18 @@ pub trait BaseSign {
        fn sign_holder_anchor_input(
                &self, anchor_tx: &Transaction, input: usize, secp_ctx: &Secp256k1<secp256k1::All>,
        ) -> Result<Signature, ()>;
-       /// Signs a channel announcement message with our funding key and our node secret key (aka
-       /// node_id or network_key), proving it comes from one of the channel participants.
+       /// Signs a channel announcement message with our funding key proving it comes from one of the
+       /// channel participants.
        ///
-       /// The first returned signature should be from our node secret key, the second from our
-       /// funding key.
+       /// Channel announcements also require a signature from each node's network key. Our node
+       /// signature is computed through [`NodeSigner::sign_gossip_message`].
        ///
        /// Note that if this fails or is rejected, the channel will not be publicly announced and
        /// our counterparty may (though likely will not) close the channel on us for violating the
        /// protocol.
-       fn sign_channel_announcement(&self, msg: &UnsignedChannelAnnouncement, secp_ctx: &Secp256k1<secp256k1::All>)
-               -> Result<(Signature, Signature), ()>;
+       fn sign_channel_announcement_with_funding_key(
+               &self, msg: &UnsignedChannelAnnouncement, secp_ctx: &Secp256k1<secp256k1::All>
+       ) -> Result<Signature, ()>;
        /// Set the counterparty static channel data, including basepoints,
        /// `counterparty_selected`/`holder_selected_contest_delay` and funding outpoint.
        ///
@@ -880,10 +881,11 @@ impl BaseSign for InMemorySigner {
                Ok(sign(secp_ctx, &hash_to_message!(&sighash[..]), &self.funding_key))
        }
 
-       fn sign_channel_announcement(&self, msg: &UnsignedChannelAnnouncement, secp_ctx: &Secp256k1<secp256k1::All>)
-       -> Result<(Signature, Signature), ()> {
+       fn sign_channel_announcement_with_funding_key(
+               &self, msg: &UnsignedChannelAnnouncement, secp_ctx: &Secp256k1<secp256k1::All>
+       ) -> Result<Signature, ()> {
                let msghash = hash_to_message!(&Sha256dHash::hash(&msg.encode()[..])[..]);
-               Ok((sign(secp_ctx, &msghash, &self.node_secret), sign(secp_ctx, &msghash, &self.funding_key)))
+               Ok(sign(secp_ctx, &msghash, &self.funding_key))
        }
 
        fn provide_channel_parameters(&mut self, channel_parameters: &ChannelTransactionParameters) {
index 8b323a3a946532c0be374b8f19931c621e16ba61..c1e7c0bcad326da46ea6ae0e88156a98d192a6f8 100644 (file)
@@ -35,7 +35,7 @@ use crate::chain::BestBlock;
 use crate::chain::chaininterface::{FeeEstimator, ConfirmationTarget, LowerBoundedFeeEstimator};
 use crate::chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateStep, LATENCY_GRACE_PERIOD_BLOCKS};
 use crate::chain::transaction::{OutPoint, TransactionData};
-use crate::chain::keysinterface::{Sign, EntropySource, BaseSign, SignerProvider};
+use crate::chain::keysinterface::{Sign, EntropySource, BaseSign, NodeSigner, Recipient, SignerProvider};
 use crate::util::events::ClosureReason;
 use crate::util::ser::{Readable, ReadableArgs, Writeable, Writer, VecWriter};
 use crate::util::logger::Logger;
@@ -2394,7 +2394,14 @@ impl<Signer: Sign> Channel<Signer> {
        /// Handles a channel_ready message from our peer. If we've already sent our channel_ready
        /// and the channel is now usable (and public), this may generate an announcement_signatures to
        /// reply with.
-       pub fn channel_ready<L: Deref>(&mut self, msg: &msgs::ChannelReady, node_pk: PublicKey, genesis_block_hash: BlockHash, user_config: &UserConfig, best_block: &BestBlock, logger: &L) -> Result<Option<msgs::AnnouncementSignatures>, ChannelError> where L::Target: Logger {
+       pub fn channel_ready<NS: Deref, L: Deref>(
+               &mut self, msg: &msgs::ChannelReady, node_signer: &NS, genesis_block_hash: BlockHash,
+               user_config: &UserConfig, best_block: &BestBlock, logger: &L
+       ) -> Result<Option<msgs::AnnouncementSignatures>, ChannelError>
+       where
+               NS::Target: NodeSigner,
+               L::Target: Logger
+       {
                if self.channel_state & (ChannelState::PeerDisconnected as u32) == ChannelState::PeerDisconnected as u32 {
                        self.workaround_lnd_bug_4006 = Some(msg.clone());
                        return Err(ChannelError::Ignore("Peer sent channel_ready when we needed a channel_reestablish. The peer is likely lnd, see https://github.com/lightningnetwork/lnd/issues/4006".to_owned()));
@@ -2448,7 +2455,7 @@ impl<Signer: Sign> Channel<Signer> {
 
                log_info!(logger, "Received channel_ready from peer for channel {}", log_bytes!(self.channel_id()));
 
-               Ok(self.get_announcement_sigs(node_pk, genesis_block_hash, user_config, best_block.height(), logger))
+               Ok(self.get_announcement_sigs(node_signer, genesis_block_hash, user_config, best_block.height(), logger))
        }
 
        /// Returns transaction if there is pending funding transaction that is yet to broadcast
@@ -3752,7 +3759,14 @@ impl<Signer: Sign> Channel<Signer> {
        /// Indicates that the latest ChannelMonitor update has been committed by the client
        /// successfully and we should restore normal operation. Returns messages which should be sent
        /// to the remote side.
-       pub fn monitor_updating_restored<L: Deref>(&mut self, logger: &L, node_pk: PublicKey, genesis_block_hash: BlockHash, user_config: &UserConfig, best_block_height: u32) -> MonitorRestoreUpdates where L::Target: Logger {
+       pub fn monitor_updating_restored<L: Deref, NS: Deref>(
+               &mut self, logger: &L, node_signer: &NS, genesis_block_hash: BlockHash,
+               user_config: &UserConfig, best_block_height: u32
+       ) -> MonitorRestoreUpdates
+       where
+               L::Target: Logger,
+               NS::Target: NodeSigner
+       {
                assert_eq!(self.channel_state & ChannelState::MonitorUpdateInProgress as u32, ChannelState::MonitorUpdateInProgress as u32);
                self.channel_state &= !(ChannelState::MonitorUpdateInProgress as u32);
 
@@ -3787,7 +3801,7 @@ impl<Signer: Sign> Channel<Signer> {
                        })
                } else { None };
 
-               let announcement_sigs = self.get_announcement_sigs(node_pk, genesis_block_hash, user_config, best_block_height, logger);
+               let announcement_sigs = self.get_announcement_sigs(node_signer, genesis_block_hash, user_config, best_block_height, logger);
 
                let mut accepted_htlcs = Vec::new();
                mem::swap(&mut accepted_htlcs, &mut self.monitor_pending_forwards);
@@ -3939,9 +3953,14 @@ impl<Signer: Sign> Channel<Signer> {
        /// `cargo doc --document-private-items`):
        /// [`super::channelmanager::ChannelManager::force_close_without_broadcasting_txn`] and
        /// [`super::channelmanager::ChannelManager::force_close_all_channels_without_broadcasting_txn`].
-       pub fn channel_reestablish<L: Deref>(&mut self, msg: &msgs::ChannelReestablish, logger: &L,
-               node_pk: PublicKey, genesis_block_hash: BlockHash, user_config: &UserConfig, best_block: &BestBlock)
-       -> Result<ReestablishResponses, ChannelError> where L::Target: Logger {
+       pub fn channel_reestablish<L: Deref, NS: Deref>(
+               &mut self, msg: &msgs::ChannelReestablish, logger: &L, node_signer: &NS,
+               genesis_block_hash: BlockHash, user_config: &UserConfig, best_block: &BestBlock
+       ) -> Result<ReestablishResponses, ChannelError>
+       where
+               L::Target: Logger,
+               NS::Target: NodeSigner
+       {
                if self.channel_state & (ChannelState::PeerDisconnected as u32) == 0 {
                        // While BOLT 2 doesn't indicate explicitly we should error this channel here, it
                        // almost certainly indicates we are going to end up out-of-sync in some way, so we
@@ -4005,7 +4024,7 @@ impl<Signer: Sign> Channel<Signer> {
                        })
                } else { None };
 
-               let announcement_sigs = self.get_announcement_sigs(node_pk, genesis_block_hash, user_config, best_block.height(), logger);
+               let announcement_sigs = self.get_announcement_sigs(node_signer, genesis_block_hash, user_config, best_block.height(), logger);
 
                if self.channel_state & (ChannelState::FundingSent as u32) == ChannelState::FundingSent as u32 {
                        // If we're waiting on a monitor update, we shouldn't re-send any channel_ready's.
@@ -4977,9 +4996,14 @@ impl<Signer: Sign> Channel<Signer> {
        /// When a transaction is confirmed, we check whether it is or spends the funding transaction
        /// In the first case, we store the confirmation height and calculating the short channel id.
        /// In the second, we simply return an Err indicating we need to be force-closed now.
-       pub fn transactions_confirmed<L: Deref>(&mut self, block_hash: &BlockHash, height: u32,
-               txdata: &TransactionData, genesis_block_hash: BlockHash, node_pk: PublicKey, user_config: &UserConfig, logger: &L)
-       -> Result<(Option<msgs::ChannelReady>, Option<msgs::AnnouncementSignatures>), ClosureReason> where L::Target: Logger {
+       pub fn transactions_confirmed<NS: Deref, L: Deref>(
+               &mut self, block_hash: &BlockHash, height: u32, txdata: &TransactionData,
+               genesis_block_hash: BlockHash, node_signer: &NS, user_config: &UserConfig, logger: &L
+       ) -> Result<(Option<msgs::ChannelReady>, Option<msgs::AnnouncementSignatures>), ClosureReason>
+       where
+               NS::Target: NodeSigner,
+               L::Target: Logger
+       {
                if let Some(funding_txo) = self.get_funding_txo() {
                        for &(index_in_block, tx) in txdata.iter() {
                                // Check if the transaction is the expected funding transaction, and if it is,
@@ -5025,7 +5049,7 @@ impl<Signer: Sign> Channel<Signer> {
                                        // may have already happened for this block).
                                        if let Some(channel_ready) = self.check_get_channel_ready(height) {
                                                log_info!(logger, "Sending a channel_ready to our peer for channel {}", log_bytes!(self.channel_id));
-                                               let announcement_sigs = self.get_announcement_sigs(node_pk, genesis_block_hash, user_config, height, logger);
+                                               let announcement_sigs = self.get_announcement_sigs(node_signer, genesis_block_hash, user_config, height, logger);
                                                return Ok((Some(channel_ready), announcement_sigs));
                                        }
                                }
@@ -5051,13 +5075,25 @@ impl<Signer: Sign> Channel<Signer> {
        ///
        /// May return some HTLCs (and their payment_hash) which have timed out and should be failed
        /// back.
-       pub fn best_block_updated<L: Deref>(&mut self, height: u32, highest_header_time: u32, genesis_block_hash: BlockHash, node_pk: PublicKey, user_config: UserConfig, logger: &L)
-       -> Result<(Option<msgs::ChannelReady>, Vec<(HTLCSource, PaymentHash)>, Option<msgs::AnnouncementSignatures>), ClosureReason> where L::Target: Logger {
-               self.do_best_block_updated(height, highest_header_time, Some((genesis_block_hash, node_pk, user_config)), logger)
+       pub fn best_block_updated<NS: Deref, L: Deref>(
+               &mut self, height: u32, highest_header_time: u32, genesis_block_hash: BlockHash,
+               node_signer: &NS, user_config: &UserConfig, logger: &L
+       ) -> Result<(Option<msgs::ChannelReady>, Vec<(HTLCSource, PaymentHash)>, Option<msgs::AnnouncementSignatures>), ClosureReason>
+       where
+               NS::Target: NodeSigner,
+               L::Target: Logger
+       {
+               self.do_best_block_updated(height, highest_header_time, Some((genesis_block_hash, node_signer, user_config)), logger)
        }
 
-       fn do_best_block_updated<L: Deref>(&mut self, height: u32, highest_header_time: u32, genesis_node_pk: Option<(BlockHash, PublicKey, UserConfig)>, logger: &L)
-       -> Result<(Option<msgs::ChannelReady>, Vec<(HTLCSource, PaymentHash)>, Option<msgs::AnnouncementSignatures>), ClosureReason> where L::Target: Logger {
+       fn do_best_block_updated<NS: Deref, L: Deref>(
+               &mut self, height: u32, highest_header_time: u32,
+               genesis_node_signer: Option<(BlockHash, &NS, &UserConfig)>, logger: &L
+       ) -> Result<(Option<msgs::ChannelReady>, Vec<(HTLCSource, PaymentHash)>, Option<msgs::AnnouncementSignatures>), ClosureReason>
+       where
+               NS::Target: NodeSigner,
+               L::Target: Logger
+       {
                let mut timed_out_htlcs = Vec::new();
                // This mirrors the check in ChannelManager::decode_update_add_htlc_onion, refusing to
                // forward an HTLC when our counterparty should almost certainly just fail it for expiring
@@ -5078,8 +5114,8 @@ impl<Signer: Sign> Channel<Signer> {
                self.update_time_counter = cmp::max(self.update_time_counter, highest_header_time);
 
                if let Some(channel_ready) = self.check_get_channel_ready(height) {
-                       let announcement_sigs = if let Some((genesis_block_hash, node_pk, user_config)) = genesis_node_pk {
-                               self.get_announcement_sigs(node_pk, genesis_block_hash, &user_config, height, logger)
+                       let announcement_sigs = if let Some((genesis_block_hash, node_signer, user_config)) = genesis_node_signer {
+                               self.get_announcement_sigs(node_signer, genesis_block_hash, user_config, height, logger)
                        } else { None };
                        log_info!(logger, "Sending a channel_ready to our peer for channel {}", log_bytes!(self.channel_id));
                        return Ok((Some(channel_ready), timed_out_htlcs, announcement_sigs));
@@ -5119,8 +5155,8 @@ impl<Signer: Sign> Channel<Signer> {
                        return Err(ClosureReason::FundingTimedOut);
                }
 
-               let announcement_sigs = if let Some((genesis_block_hash, node_pk, user_config)) = genesis_node_pk {
-                       self.get_announcement_sigs(node_pk, genesis_block_hash, &user_config, height, logger)
+               let announcement_sigs = if let Some((genesis_block_hash, node_signer, user_config)) = genesis_node_signer {
+                       self.get_announcement_sigs(node_signer, genesis_block_hash, user_config, height, logger)
                } else { None };
                Ok((None, timed_out_htlcs, announcement_sigs))
        }
@@ -5137,7 +5173,7 @@ impl<Signer: Sign> Channel<Signer> {
                        // larger. If we don't know that time has moved forward, we can just set it to the last
                        // time we saw and it will be ignored.
                        let best_time = self.update_time_counter;
-                       match self.do_best_block_updated(reorg_height, best_time, None, logger) {
+                       match self.do_best_block_updated(reorg_height, best_time, None::<(BlockHash, &&NodeSigner, &UserConfig)>, logger) {
                                Ok((channel_ready, timed_out_htlcs, announcement_sigs)) => {
                                        assert!(channel_ready.is_none(), "We can't generate a funding with 0 confirmations?");
                                        assert!(timed_out_htlcs.is_empty(), "We can't have accepted HTLCs with a timeout before our funding confirmation?");
@@ -5337,7 +5373,9 @@ impl<Signer: Sign> Channel<Signer> {
        /// closing).
        ///
        /// This will only return ChannelError::Ignore upon failure.
-       fn get_channel_announcement(&self, node_id: PublicKey, chain_hash: BlockHash, user_config: &UserConfig) -> Result<msgs::UnsignedChannelAnnouncement, ChannelError> {
+       fn get_channel_announcement<NS: Deref>(
+               &self, node_signer: &NS, chain_hash: BlockHash, user_config: &UserConfig,
+       ) -> Result<msgs::UnsignedChannelAnnouncement, ChannelError> where NS::Target: NodeSigner {
                if !self.config.announced_channel {
                        return Err(ChannelError::Ignore("Channel is not available for public announcements".to_owned()));
                }
@@ -5345,6 +5383,8 @@ impl<Signer: Sign> Channel<Signer> {
                        return Err(ChannelError::Ignore("Cannot get a ChannelAnnouncement if the channel is not currently usable".to_owned()));
                }
 
+               let node_id = node_signer.get_node_id(Recipient::Node)
+                       .map_err(|_| ChannelError::Ignore("Failed to retrieve own public key".to_owned()))?;
                let were_node_one = node_id.serialize()[..] < self.counterparty_node_id.serialize()[..];
 
                let msg = msgs::UnsignedChannelAnnouncement {
@@ -5361,8 +5401,14 @@ impl<Signer: Sign> Channel<Signer> {
                Ok(msg)
        }
 
-       fn get_announcement_sigs<L: Deref>(&mut self, node_pk: PublicKey, genesis_block_hash: BlockHash, user_config: &UserConfig, best_block_height: u32, logger: &L)
-       -> Option<msgs::AnnouncementSignatures> where L::Target: Logger {
+       fn get_announcement_sigs<NS: Deref, L: Deref>(
+               &mut self, node_signer: &NS, genesis_block_hash: BlockHash, user_config: &UserConfig,
+               best_block_height: u32, logger: &L
+       ) -> Option<msgs::AnnouncementSignatures>
+       where
+               NS::Target: NodeSigner,
+               L::Target: Logger
+       {
                if self.funding_tx_confirmation_height == 0 || self.funding_tx_confirmation_height + 5 > best_block_height {
                        return None;
                }
@@ -5381,14 +5427,21 @@ impl<Signer: Sign> Channel<Signer> {
                }
 
                log_trace!(logger, "Creating an announcement_signatures message for channel {}", log_bytes!(self.channel_id()));
-               let announcement = match self.get_channel_announcement(node_pk, genesis_block_hash, user_config) {
+               let announcement = match self.get_channel_announcement(node_signer, genesis_block_hash, user_config) {
                        Ok(a) => a,
-                       Err(_) => {
-                               log_trace!(logger, "Cannot create an announcement_signatures as channel is not public.");
+                       Err(e) => {
+                               log_trace!(logger, "{:?}", e);
                                return None;
                        }
                };
-               let (our_node_sig, our_bitcoin_sig) = match self.holder_signer.sign_channel_announcement(&announcement, &self.secp_ctx) {
+               let our_node_sig = match node_signer.sign_gossip_message(msgs::UnsignedGossipMessage::ChannelAnnouncement(&announcement)) {
+                       Err(_) => {
+                               log_error!(logger, "Failed to generate node signature for channel_announcement. Channel will not be announced!");
+                               return None;
+                       },
+                       Ok(v) => v
+               };
+               let our_bitcoin_sig = match self.holder_signer.sign_channel_announcement_with_funding_key(&announcement, &self.secp_ctx) {
                        Err(_) => {
                                log_error!(logger, "Signer rejected channel_announcement signing. Channel will not be announced!");
                                return None;
@@ -5407,11 +5460,17 @@ impl<Signer: Sign> Channel<Signer> {
 
        /// Signs the given channel announcement, returning a ChannelError::Ignore if no keys are
        /// available.
-       fn sign_channel_announcement(&self, our_node_id: PublicKey, announcement: msgs::UnsignedChannelAnnouncement) -> Result<msgs::ChannelAnnouncement, ChannelError> {
+       fn sign_channel_announcement<NS: Deref>(
+               &self, node_signer: &NS, announcement: msgs::UnsignedChannelAnnouncement
+       ) -> Result<msgs::ChannelAnnouncement, ChannelError> where NS::Target: NodeSigner {
                if let Some((their_node_sig, their_bitcoin_sig)) = self.announcement_sigs {
-                       let were_node_one = announcement.node_id_1 == our_node_id;
+                       let our_node_key = node_signer.get_node_id(Recipient::Node)
+                               .map_err(|_| ChannelError::Ignore("Signer failed to retrieve own public key".to_owned()))?;
+                       let were_node_one = announcement.node_id_1 == our_node_key;
 
-                       let (our_node_sig, our_bitcoin_sig) = self.holder_signer.sign_channel_announcement(&announcement, &self.secp_ctx)
+                       let our_node_sig = node_signer.sign_gossip_message(msgs::UnsignedGossipMessage::ChannelAnnouncement(&announcement))
+                               .map_err(|_| ChannelError::Ignore("Failed to generate node signature for channel_announcement".to_owned()))?;
+                       let our_bitcoin_sig = self.holder_signer.sign_channel_announcement_with_funding_key(&announcement, &self.secp_ctx)
                                .map_err(|_| ChannelError::Ignore("Signer rejected channel_announcement".to_owned()))?;
                        Ok(msgs::ChannelAnnouncement {
                                node_signature_1: if were_node_one { our_node_sig } else { their_node_sig },
@@ -5428,8 +5487,11 @@ impl<Signer: Sign> Channel<Signer> {
        /// Processes an incoming announcement_signatures message, providing a fully-signed
        /// channel_announcement message which we can broadcast and storing our counterparty's
        /// signatures for later reconstruction/rebroadcast of the channel_announcement.
-       pub fn announcement_signatures(&mut self, our_node_id: PublicKey, chain_hash: BlockHash, best_block_height: u32, msg: &msgs::AnnouncementSignatures, user_config: &UserConfig) -> Result<msgs::ChannelAnnouncement, ChannelError> {
-               let announcement = self.get_channel_announcement(our_node_id.clone(), chain_hash, user_config)?;
+       pub fn announcement_signatures<NS: Deref>(
+               &mut self, node_signer: &NS, chain_hash: BlockHash, best_block_height: u32,
+               msg: &msgs::AnnouncementSignatures, user_config: &UserConfig
+       ) -> Result<msgs::ChannelAnnouncement, ChannelError> where NS::Target: NodeSigner {
+               let announcement = self.get_channel_announcement(node_signer, chain_hash, user_config)?;
 
                let msghash = hash_to_message!(&Sha256d::hash(&announcement.encode()[..])[..]);
 
@@ -5450,20 +5512,22 @@ impl<Signer: Sign> Channel<Signer> {
                                "Got announcement_signatures prior to the required six confirmations - we may not have received a block yet that our peer has".to_owned()));
                }
 
-               self.sign_channel_announcement(our_node_id, announcement)
+               self.sign_channel_announcement(node_signer, announcement)
        }
 
        /// Gets a signed channel_announcement for this channel, if we previously received an
        /// announcement_signatures from our counterparty.
-       pub fn get_signed_channel_announcement(&self, our_node_id: PublicKey, chain_hash: BlockHash, best_block_height: u32, user_config: &UserConfig) -> Option<msgs::ChannelAnnouncement> {
+       pub fn get_signed_channel_announcement<NS: Deref>(
+               &self, node_signer: &NS, chain_hash: BlockHash, best_block_height: u32, user_config: &UserConfig
+       ) -> Option<msgs::ChannelAnnouncement> where NS::Target: NodeSigner {
                if self.funding_tx_confirmation_height == 0 || self.funding_tx_confirmation_height + 5 > best_block_height {
                        return None;
                }
-               let announcement = match self.get_channel_announcement(our_node_id.clone(), chain_hash, user_config) {
+               let announcement = match self.get_channel_announcement(node_signer, chain_hash, user_config) {
                        Ok(res) => res,
                        Err(_) => return None,
                };
-               match self.sign_channel_announcement(our_node_id, announcement) {
+               match self.sign_channel_announcement(node_signer, announcement) {
                        Ok(res) => Some(res),
                        Err(_) => None,
                }
index 5b312f04e4a13ba987539a8bde2481f42cd20550..abec2c95a185b9e2a483cfff629c9871b342839e 100644 (file)
@@ -26,7 +26,6 @@ use bitcoin::network::constants::Network;
 
 use bitcoin::hashes::Hash;
 use bitcoin::hashes::sha256::Hash as Sha256;
-use bitcoin::hashes::sha256d::Hash as Sha256dHash;
 use bitcoin::hash_types::{BlockHash, Txid};
 
 use bitcoin::secp256k1::{SecretKey,PublicKey};
@@ -2280,9 +2279,11 @@ where
                        fee_proportional_millionths: chan.get_fee_proportional_millionths(),
                        excess_data: Vec::new(),
                };
-
-               let msg_hash = Sha256dHash::hash(&unsigned.encode()[..]);
-               let sig = self.secp_ctx.sign_ecdsa(&hash_to_message!(&msg_hash[..]), &self.our_network_key);
+               // Panic on failure to signal LDK should be restarted to retry signing the `ChannelUpdate`.
+               // If we returned an error and the `node_signer` cannot provide a signature for whatever
+               // reason`, we wouldn't be able to receive inbound payments through the corresponding
+               // channel.
+               let sig = self.node_signer.sign_gossip_message(msgs::UnsignedGossipMessage::ChannelUpdate(&unsigned)).unwrap();
 
                Ok(msgs::ChannelUpdate {
                        signature: sig,
@@ -4060,7 +4061,7 @@ where
                                return;
                        }
 
-                       let updates = channel.get_mut().monitor_updating_restored(&self.logger, self.get_our_node_id(), self.genesis_hash, &self.default_configuration, self.best_block.read().unwrap().height());
+                       let updates = channel.get_mut().monitor_updating_restored(&self.logger, &self.node_signer, self.genesis_hash, &self.default_configuration, self.best_block.read().unwrap().height());
                        let channel_update = if updates.channel_ready.is_some() && channel.get().is_usable() {
                                // We only send a channel_update in the case where we are just now sending a
                                // channel_ready and the channel is in a usable state. We may re-send a
@@ -4397,7 +4398,7 @@ where
                let peer_state = &mut *peer_state_lock;
                match peer_state.channel_by_id.entry(msg.channel_id) {
                        hash_map::Entry::Occupied(mut chan) => {
-                               let announcement_sigs_opt = try_chan_entry!(self, chan.get_mut().channel_ready(&msg, self.get_our_node_id(),
+                               let announcement_sigs_opt = try_chan_entry!(self, chan.get_mut().channel_ready(&msg, &self.node_signer,
                                        self.genesis_hash.clone(), &self.default_configuration, &self.best_block.read().unwrap(), &self.logger), chan);
                                if let Some(announcement_sigs) = announcement_sigs_opt {
                                        log_trace!(self.logger, "Sending announcement_signatures for channel {}", log_bytes!(chan.get().channel_id()));
@@ -4879,8 +4880,8 @@ where
 
                                peer_state.pending_msg_events.push(events::MessageSendEvent::BroadcastChannelAnnouncement {
                                        msg: try_chan_entry!(self, chan.get_mut().announcement_signatures(
-                                               self.get_our_node_id(), self.genesis_hash.clone(),
-                                               self.best_block.read().unwrap().height(), msg, &self.default_configuration
+                                               &self.node_signer, self.genesis_hash.clone(), self.best_block.read().unwrap().height(),
+                                               msg, &self.default_configuration
                                        ), chan),
                                        // Note that announcement_signatures fails if the channel cannot be announced,
                                        // so get_channel_update_for_broadcast will never fail by the time we get here.
@@ -4951,7 +4952,7 @@ where
                                        // freed HTLCs to fail backwards. If in the future we no longer drop pending
                                        // add-HTLCs on disconnect, we may be handed HTLCs to fail backwards here.
                                        let responses = try_chan_entry!(self, chan.get_mut().channel_reestablish(
-                                               msg, &self.logger, self.our_network_pubkey.clone(), self.genesis_hash,
+                                               msg, &self.logger, &self.node_signer, self.genesis_hash,
                                                &self.default_configuration, &*self.best_block.read().unwrap()), chan);
                                        let mut channel_update = None;
                                        if let Some(msg) = responses.shutdown_msg {
@@ -5630,7 +5631,7 @@ where
                        *best_block = BestBlock::new(header.prev_blockhash, new_height)
                }
 
-               self.do_chain_event(Some(new_height), |channel| channel.best_block_updated(new_height, header.time, self.genesis_hash.clone(), self.get_our_node_id(), self.default_configuration.clone(), &self.logger));
+               self.do_chain_event(Some(new_height), |channel| channel.best_block_updated(new_height, header.time, self.genesis_hash.clone(), &self.node_signer, &self.default_configuration, &self.logger));
        }
 }
 
@@ -5654,13 +5655,13 @@ where
                log_trace!(self.logger, "{} transactions included in block {} at height {} provided", txdata.len(), block_hash, height);
 
                let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier);
-               self.do_chain_event(Some(height), |channel| channel.transactions_confirmed(&block_hash, height, txdata, self.genesis_hash.clone(), self.get_our_node_id(), &self.default_configuration, &self.logger)
+               self.do_chain_event(Some(height), |channel| channel.transactions_confirmed(&block_hash, height, txdata, self.genesis_hash.clone(), &self.node_signer, &self.default_configuration, &self.logger)
                        .map(|(a, b)| (a, Vec::new(), b)));
 
                let last_best_block_height = self.best_block.read().unwrap().height();
                if height < last_best_block_height {
                        let timestamp = self.highest_seen_timestamp.load(Ordering::Acquire);
-                       self.do_chain_event(Some(last_best_block_height), |channel| channel.best_block_updated(last_best_block_height, timestamp as u32, self.genesis_hash.clone(), self.get_our_node_id(), self.default_configuration.clone(), &self.logger));
+                       self.do_chain_event(Some(last_best_block_height), |channel| channel.best_block_updated(last_best_block_height, timestamp as u32, self.genesis_hash.clone(), &self.node_signer, &self.default_configuration, &self.logger));
                }
        }
 
@@ -5676,7 +5677,7 @@ where
 
                *self.best_block.write().unwrap() = BestBlock::new(block_hash, height);
 
-               self.do_chain_event(Some(height), |channel| channel.best_block_updated(height, header.time, self.genesis_hash.clone(), self.get_our_node_id(), self.default_configuration.clone(), &self.logger));
+               self.do_chain_event(Some(height), |channel| channel.best_block_updated(height, header.time, self.genesis_hash.clone(), &self.node_signer, &self.default_configuration, &self.logger));
 
                macro_rules! max_time {
                        ($timestamp: expr) => {
@@ -5787,7 +5788,7 @@ where
                                                                msg: announcement_sigs,
                                                        });
                                                        if let Some(height) = height_opt {
-                                                               if let Some(announcement) = channel.get_signed_channel_announcement(self.get_our_node_id(), self.genesis_hash, height, &self.default_configuration) {
+                                                               if let Some(announcement) = channel.get_signed_channel_announcement(&self.node_signer, self.genesis_hash, height, &self.default_configuration) {
                                                                        pending_msg_events.push(events::MessageSendEvent::BroadcastChannelAnnouncement {
                                                                                msg: announcement,
                                                                                // Note that announcement_signatures fails if the channel cannot be announced,
@@ -6177,7 +6178,7 @@ where
                                        }
                                } else { true };
                                if retain && chan.get_counterparty_node_id() != *counterparty_node_id {
-                                       if let Some(msg) = chan.get_signed_channel_announcement(self.get_our_node_id(), self.genesis_hash.clone(), self.best_block.read().unwrap().height(), &self.default_configuration) {
+                                       if let Some(msg) = chan.get_signed_channel_announcement(&self.node_signer, self.genesis_hash.clone(), self.best_block.read().unwrap().height(), &self.default_configuration) {
                                                if let Ok(update_msg) = self.get_channel_update_for_broadcast(chan) {
                                                        pending_msg_events.push(events::MessageSendEvent::SendChannelAnnouncement {
                                                                node_id: *counterparty_node_id,
index dffda9967badfe28b5afb3d2ebc0a3a4457e18fd..9983f6f90d39334d99a9ae5a06342a62b9e90ec3 100644 (file)
@@ -17,6 +17,7 @@
 
 use bitcoin::secp256k1::{self, Secp256k1, SecretKey, PublicKey};
 
+use crate::chain::keysinterface::{KeysManager, NodeSigner, Recipient};
 use crate::ln::features::{InitFeatures, NodeFeatures};
 use crate::ln::msgs;
 use crate::ln::msgs::{ChannelMessageHandler, LightningError, NetAddress, OnionMessageHandler, RoutingMessageHandler};
@@ -28,7 +29,6 @@ use crate::ln::wire::Encode;
 use crate::onion_message::{CustomOnionMessageContents, CustomOnionMessageHandler, SimpleArcOnionMessenger, SimpleRefOnionMessenger};
 use crate::routing::gossip::{NetworkGraph, P2PGossipSync};
 use crate::util::atomic_counter::AtomicCounter;
-use crate::util::crypto::sign;
 use crate::util::events::{MessageSendEvent, MessageSendEventsProvider, OnionMessageProvider};
 use crate::util::logger::Logger;
 
@@ -43,7 +43,6 @@ use core::convert::Infallible;
 #[cfg(feature = "std")] use std::error;
 
 use bitcoin::hashes::sha256::Hash as Sha256;
-use bitcoin::hashes::sha256d::Hash as Sha256dHash;
 use bitcoin::hashes::sha256::HashEngine as Sha256Engine;
 use bitcoin::hashes::{HashEngine, Hash};
 
@@ -491,7 +490,7 @@ impl Peer {
 /// issues such as overly long function definitions.
 ///
 /// (C-not exported) as `Arc`s don't make sense in bindings.
-pub type SimpleArcPeerManager<SD, M, T, F, C, L> = PeerManager<SD, Arc<SimpleArcChannelManager<M, T, F, L>>, Arc<P2PGossipSync<Arc<NetworkGraph<Arc<L>>>, Arc<C>, Arc<L>>>, Arc<SimpleArcOnionMessenger<L>>, Arc<L>, IgnoringMessageHandler>;
+pub type SimpleArcPeerManager<SD, M, T, F, C, L> = PeerManager<SD, Arc<SimpleArcChannelManager<M, T, F, L>>, Arc<P2PGossipSync<Arc<NetworkGraph<Arc<L>>>, Arc<C>, Arc<L>>>, Arc<SimpleArcOnionMessenger<L>>, Arc<L>, IgnoringMessageHandler, Arc<KeysManager>>;
 
 /// SimpleRefPeerManager is a type alias for a PeerManager reference, and is the reference
 /// counterpart to the SimpleArcPeerManager type alias. Use this type by default when you don't
@@ -501,7 +500,7 @@ pub type SimpleArcPeerManager<SD, M, T, F, C, L> = PeerManager<SD, Arc<SimpleArc
 /// helps with issues such as long function definitions.
 ///
 /// (C-not exported) as general type aliases don't make sense in bindings.
-pub type SimpleRefPeerManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k, 'l, 'm, SD, M, T, F, C, L> = PeerManager<SD, SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'm, M, T, F, L>, &'f P2PGossipSync<&'g NetworkGraph<&'f L>, &'h C, &'f L>, &'i SimpleRefOnionMessenger<'j, 'k, L>, &'f L, IgnoringMessageHandler>;
+pub type SimpleRefPeerManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k, 'l, 'm, SD, M, T, F, C, L> = PeerManager<SD, SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'm, M, T, F, L>, &'f P2PGossipSync<&'g NetworkGraph<&'f L>, &'h C, &'f L>, &'i SimpleRefOnionMessenger<'j, 'k, L>, &'f L, IgnoringMessageHandler, &'c KeysManager>;
 
 /// A PeerManager manages a set of peers, described by their [`SocketDescriptor`] and marshalls
 /// socket events into messages which it passes on to its [`MessageHandler`].
@@ -522,12 +521,13 @@ pub type SimpleRefPeerManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k, 'l, 'm
 /// you're using lightning-net-tokio.
 ///
 /// [`read_event`]: PeerManager::read_event
-pub struct PeerManager<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CMH: Deref> where
+pub struct PeerManager<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CMH: Deref, NS: Deref> where
                CM::Target: ChannelMessageHandler,
                RM::Target: RoutingMessageHandler,
                OM::Target: OnionMessageHandler,
                L::Target: Logger,
-               CMH::Target: CustomMessageHandler {
+               CMH::Target: CustomMessageHandler,
+               NS::Target: NodeSigner {
        message_handler: MessageHandler<CM, RM, OM>,
        /// Connection state for each connected peer - we have an outer read-write lock which is taken
        /// as read while we're doing processing for a peer and taken write when a peer is being added
@@ -563,6 +563,8 @@ pub struct PeerManager<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: D
 
        peer_counter: AtomicCounter,
 
+       node_signer: NS,
+
        logger: L,
        secp_ctx: Secp256k1<secp256k1::SignOnly>
 }
@@ -592,10 +594,11 @@ macro_rules! encode_msg {
        }}
 }
 
-impl<Descriptor: SocketDescriptor, CM: Deref, OM: Deref, L: Deref> PeerManager<Descriptor, CM, IgnoringMessageHandler, OM, L, IgnoringMessageHandler> where
+impl<Descriptor: SocketDescriptor, CM: Deref, OM: Deref, L: Deref, NS: Deref> PeerManager<Descriptor, CM, IgnoringMessageHandler, OM, L, IgnoringMessageHandler, NS> where
                CM::Target: ChannelMessageHandler,
                OM::Target: OnionMessageHandler,
-               L::Target: Logger {
+               L::Target: Logger,
+               NS::Target: NodeSigner {
        /// Constructs a new `PeerManager` with the given `ChannelMessageHandler` and
        /// `OnionMessageHandler`. No routing message handler is used and network graph messages are
        /// ignored.
@@ -609,18 +612,19 @@ impl<Descriptor: SocketDescriptor, CM: Deref, OM: Deref, L: Deref> PeerManager<D
        /// minute should suffice.
        ///
        /// (C-not exported) as we can't export a PeerManager with a dummy route handler
-       pub fn new_channel_only(channel_message_handler: CM, onion_message_handler: OM, our_node_secret: SecretKey, current_time: u32, ephemeral_random_data: &[u8; 32], logger: L) -> Self {
+       pub fn new_channel_only(channel_message_handler: CM, onion_message_handler: OM, our_node_secret: SecretKey, current_time: u32, ephemeral_random_data: &[u8; 32], logger: L, node_signer: NS) -> Self {
                Self::new(MessageHandler {
                        chan_handler: channel_message_handler,
                        route_handler: IgnoringMessageHandler{},
                        onion_message_handler,
-               }, our_node_secret, current_time, ephemeral_random_data, logger, IgnoringMessageHandler{})
+               }, our_node_secret, current_time, ephemeral_random_data, logger, IgnoringMessageHandler{}, node_signer)
        }
 }
 
-impl<Descriptor: SocketDescriptor, RM: Deref, L: Deref> PeerManager<Descriptor, ErroringMessageHandler, RM, IgnoringMessageHandler, L, IgnoringMessageHandler> where
+impl<Descriptor: SocketDescriptor, RM: Deref, L: Deref, NS: Deref> PeerManager<Descriptor, ErroringMessageHandler, RM, IgnoringMessageHandler, L, IgnoringMessageHandler, NS> where
                RM::Target: RoutingMessageHandler,
-               L::Target: Logger {
+               L::Target: Logger,
+               NS::Target: NodeSigner {
        /// Constructs a new `PeerManager` with the given `RoutingMessageHandler`. No channel message
        /// handler or onion message handler is used and onion and channel messages will be ignored (or
        /// generate error messages). Note that some other lightning implementations time-out connections
@@ -635,12 +639,12 @@ impl<Descriptor: SocketDescriptor, RM: Deref, L: Deref> PeerManager<Descriptor,
        /// cryptographically secure random bytes.
        ///
        /// (C-not exported) as we can't export a PeerManager with a dummy channel handler
-       pub fn new_routing_only(routing_message_handler: RM, our_node_secret: SecretKey, current_time: u32, ephemeral_random_data: &[u8; 32], logger: L) -> Self {
+       pub fn new_routing_only(routing_message_handler: RM, our_node_secret: SecretKey, current_time: u32, ephemeral_random_data: &[u8; 32], logger: L, node_signer: NS) -> Self {
                Self::new(MessageHandler {
                        chan_handler: ErroringMessageHandler::new(),
                        route_handler: routing_message_handler,
                        onion_message_handler: IgnoringMessageHandler{},
-               }, our_node_secret, current_time, ephemeral_random_data, logger, IgnoringMessageHandler{})
+               }, our_node_secret, current_time, ephemeral_random_data, logger, IgnoringMessageHandler{}, node_signer)
        }
 }
 
@@ -685,12 +689,14 @@ fn filter_addresses(ip_address: Option<NetAddress>) -> Option<NetAddress> {
        }
 }
 
-impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CMH: Deref> PeerManager<Descriptor, CM, RM, OM, L, CMH> where
+impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CMH: Deref, NS: Deref> PeerManager<Descriptor, CM, RM, OM, L, CMH, NS> where
                CM::Target: ChannelMessageHandler,
                RM::Target: RoutingMessageHandler,
                OM::Target: OnionMessageHandler,
                L::Target: Logger,
-               CMH::Target: CustomMessageHandler {
+               CMH::Target: CustomMessageHandler,
+               NS::Target: NodeSigner
+{
        /// Constructs a new PeerManager with the given message handlers and node_id secret key
        /// ephemeral_random_data is used to derive per-connection ephemeral keys and must be
        /// cryptographically secure random bytes.
@@ -699,7 +705,7 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
        /// incremented irregularly internally. In general it is best to simply use the current UNIX
        /// timestamp, however if it is not available a persistent counter that increases once per
        /// minute should suffice.
-       pub fn new(message_handler: MessageHandler<CM, RM, OM>, our_node_secret: SecretKey, current_time: u32, ephemeral_random_data: &[u8; 32], logger: L, custom_message_handler: CMH) -> Self {
+       pub fn new(message_handler: MessageHandler<CM, RM, OM>, our_node_secret: SecretKey, current_time: u32, ephemeral_random_data: &[u8; 32], logger: L, custom_message_handler: CMH, node_signer: NS) -> Self {
                let mut ephemeral_key_midstate = Sha256::engine();
                ephemeral_key_midstate.input(ephemeral_random_data);
 
@@ -719,6 +725,7 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
                        last_node_announcement_serial: AtomicU32::new(current_time),
                        logger,
                        custom_message_handler,
+                       node_signer,
                        secp_ctx,
                }
        }
@@ -2016,13 +2023,20 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
                let announcement = msgs::UnsignedNodeAnnouncement {
                        features,
                        timestamp: self.last_node_announcement_serial.fetch_add(1, Ordering::AcqRel),
-                       node_id: PublicKey::from_secret_key(&self.secp_ctx, &self.our_node_secret),
+                       node_id: self.node_signer.get_node_id(Recipient::Node).unwrap(),
                        rgb, alias, addresses,
                        excess_address_data: Vec::new(),
                        excess_data: Vec::new(),
                };
-               let msghash = hash_to_message!(&Sha256dHash::hash(&announcement.encode()[..])[..]);
-               let node_announce_sig = sign(&self.secp_ctx, &msghash, &self.our_node_secret);
+               let node_announce_sig = match self.node_signer.sign_gossip_message(
+                       msgs::UnsignedGossipMessage::NodeAnnouncement(&announcement)
+               ) {
+                       Ok(sig) => sig,
+                       Err(_) => {
+                               log_error!(self.logger, "Failed to generate signature for node_announcement");
+                               return;
+                       },
+               };
 
                let msg = msgs::NodeAnnouncement {
                        signature: node_announce_sig,
@@ -2093,16 +2107,19 @@ mod tests {
                chan_handler: test_utils::TestChannelMessageHandler,
                routing_handler: test_utils::TestRoutingMessageHandler,
                logger: test_utils::TestLogger,
+               node_signer: test_utils::TestNodeSigner,
        }
 
        fn create_peermgr_cfgs(peer_count: usize) -> Vec<PeerManagerCfg> {
                let mut cfgs = Vec::new();
-               for _ in 0..peer_count {
+               for i in 0..peer_count {
+                       let node_secret = SecretKey::from_slice(&[42 + i as u8; 32]).unwrap();
                        cfgs.push(
                                PeerManagerCfg{
                                        chan_handler: test_utils::TestChannelMessageHandler::new(),
                                        logger: test_utils::TestLogger::new(),
                                        routing_handler: test_utils::TestRoutingMessageHandler::new(),
+                                       node_signer: test_utils::TestNodeSigner::new(node_secret),
                                }
                        );
                }
@@ -2110,20 +2127,20 @@ mod tests {
                cfgs
        }
 
-       fn create_network<'a>(peer_count: usize, cfgs: &'a Vec<PeerManagerCfg>) -> Vec<PeerManager<FileDescriptor, &'a test_utils::TestChannelMessageHandler, &'a test_utils::TestRoutingMessageHandler, IgnoringMessageHandler, &'a test_utils::TestLogger, IgnoringMessageHandler>> {
+       fn create_network<'a>(peer_count: usize, cfgs: &'a Vec<PeerManagerCfg>) -> Vec<PeerManager<FileDescriptor, &'a test_utils::TestChannelMessageHandler, &'a test_utils::TestRoutingMessageHandler, IgnoringMessageHandler, &'a test_utils::TestLogger, IgnoringMessageHandler, &'a test_utils::TestNodeSigner>> {
                let mut peers = Vec::new();
                for i in 0..peer_count {
                        let node_secret = SecretKey::from_slice(&[42 + i as u8; 32]).unwrap();
                        let ephemeral_bytes = [i as u8; 32];
                        let msg_handler = MessageHandler { chan_handler: &cfgs[i].chan_handler, route_handler: &cfgs[i].routing_handler, onion_message_handler: IgnoringMessageHandler {} };
-                       let peer = PeerManager::new(msg_handler, node_secret, 0, &ephemeral_bytes, &cfgs[i].logger, IgnoringMessageHandler {});
+                       let peer = PeerManager::new(msg_handler, node_secret, 0, &ephemeral_bytes, &cfgs[i].logger, IgnoringMessageHandler {}, &cfgs[i].node_signer);
                        peers.push(peer);
                }
 
                peers
        }
 
-       fn establish_connection<'a>(peer_a: &PeerManager<FileDescriptor, &'a test_utils::TestChannelMessageHandler, &'a test_utils::TestRoutingMessageHandler, IgnoringMessageHandler, &'a test_utils::TestLogger, IgnoringMessageHandler>, peer_b: &PeerManager<FileDescriptor, &'a test_utils::TestChannelMessageHandler, &'a test_utils::TestRoutingMessageHandler, IgnoringMessageHandler, &'a test_utils::TestLogger, IgnoringMessageHandler>) -> (FileDescriptor, FileDescriptor) {
+       fn establish_connection<'a>(peer_a: &PeerManager<FileDescriptor, &'a test_utils::TestChannelMessageHandler, &'a test_utils::TestRoutingMessageHandler, IgnoringMessageHandler, &'a test_utils::TestLogger, IgnoringMessageHandler, &'a test_utils::TestNodeSigner>, peer_b: &PeerManager<FileDescriptor, &'a test_utils::TestChannelMessageHandler, &'a test_utils::TestRoutingMessageHandler, IgnoringMessageHandler, &'a test_utils::TestLogger, IgnoringMessageHandler, &'a test_utils::TestNodeSigner>) -> (FileDescriptor, FileDescriptor) {
                let secp_ctx = Secp256k1::new();
                let a_id = PublicKey::from_secret_key(&secp_ctx, &peer_a.our_node_secret);
                let mut fd_a = FileDescriptor { fd: 1, outbound_data: Arc::new(Mutex::new(Vec::new())) };
index 9bfed7e2c2029547f5fcf603c7a9c684181c48f0..aca781b9fd6f50ef2908d4fa518678c932ec522f 100644 (file)
@@ -12,7 +12,7 @@
 //! LSP).
 
 use crate::chain::ChannelMonitorUpdateStatus;
-use crate::chain::keysinterface::{Recipient, NodeSigner};
+use crate::chain::keysinterface::NodeSigner;
 use crate::ln::channelmanager::{ChannelManager, MIN_CLTV_EXPIRY_DELTA, PaymentId};
 use crate::routing::gossip::RoutingFees;
 use crate::routing::router::{PaymentParameters, RouteHint, RouteHintHop};
@@ -31,10 +31,7 @@ use core::default::Default;
 use crate::ln::functional_test_utils::*;
 
 use bitcoin::blockdata::constants::genesis_block;
-use bitcoin::hashes::Hash;
-use bitcoin::hashes::sha256d::Hash as Sha256dHash;
 use bitcoin::network::constants::Network;
-use bitcoin::secp256k1::Secp256k1;
 
 #[test]
 fn test_priv_forwarding_rejection() {
@@ -493,8 +490,7 @@ fn test_scid_alias_returned() {
                fee_proportional_millionths: last_hop[0].counterparty.forwarding_info.as_ref().unwrap().fee_proportional_millionths,
                excess_data: Vec::new(),
        };
-       let msg_hash = Sha256dHash::hash(&contents.encode()[..]);
-       let signature = Secp256k1::new().sign_ecdsa(&hash_to_message!(&msg_hash[..]), &nodes[1].keys_manager.get_node_secret(Recipient::Node).unwrap());
+       let signature = nodes[1].keys_manager.sign_gossip_message(msgs::UnsignedGossipMessage::ChannelUpdate(&contents)).unwrap();
        let msg = msgs::ChannelUpdate { signature, contents };
 
        let mut err_data = Vec::new();
index dfec1be7e91bc5896882560afa2939d46f0b0318..769d00ecf557500b5f79ba94a84ff761cdc07bee 100644 (file)
@@ -223,9 +223,10 @@ impl BaseSign for EnforcingSigner {
                self.inner.sign_holder_anchor_input(anchor_tx, input, secp_ctx)
        }
 
-       fn sign_channel_announcement(&self, msg: &msgs::UnsignedChannelAnnouncement, secp_ctx: &Secp256k1<secp256k1::All>)
-       -> Result<(Signature, Signature), ()> {
-               self.inner.sign_channel_announcement(msg, secp_ctx)
+       fn sign_channel_announcement_with_funding_key(
+               &self, msg: &msgs::UnsignedChannelAnnouncement, secp_ctx: &Secp256k1<secp256k1::All>
+       ) -> Result<Signature, ()> {
+               self.inner.sign_channel_announcement_with_funding_key(msg, secp_ctx)
        }
 
        fn provide_channel_parameters(&mut self, channel_parameters: &ChannelTransactionParameters) {
index 9fb5178ad9d00b7a34f5cc99226aac62d6db8041..9b081654398eafeaf20829bb1934632f2b36da23 100644 (file)
@@ -621,6 +621,57 @@ impl Logger for TestLogger {
        }
 }
 
+pub struct TestNodeSigner {
+       node_secret: SecretKey,
+}
+
+impl TestNodeSigner {
+       pub fn new(node_secret: SecretKey) -> Self {
+               Self { node_secret }
+       }
+}
+
+impl NodeSigner for TestNodeSigner {
+       fn get_node_secret(&self, recipient: Recipient) -> Result<SecretKey, ()> {
+               let node_secret = match recipient {
+                       Recipient::Node => Ok(self.node_secret.clone()),
+                       Recipient::PhantomNode => Err(())
+               }?;
+               Ok(node_secret)
+       }
+
+       fn get_inbound_payment_key_material(&self) -> crate::chain::keysinterface::KeyMaterial {
+               unreachable!()
+       }
+
+       fn get_node_id(&self, recipient: Recipient) -> Result<PublicKey, ()> {
+               let node_secret = match recipient {
+                       Recipient::Node => Ok(&self.node_secret),
+                       Recipient::PhantomNode => Err(())
+               }?;
+               Ok(PublicKey::from_secret_key(&Secp256k1::signing_only(), node_secret))
+       }
+
+       fn ecdh(&self, recipient: Recipient, other_key: &PublicKey, tweak: Option<&bitcoin::secp256k1::Scalar>) -> Result<SharedSecret, ()> {
+               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(|_| ())?;
+               }
+               Ok(SharedSecret::new(other_key, &node_secret))
+       }
+
+       fn sign_invoice(&self, _: &[u8], _: &[bitcoin::bech32::u5], _: Recipient) -> Result<bitcoin::secp256k1::ecdsa::RecoverableSignature, ()> {
+               unreachable!()
+       }
+
+       fn sign_gossip_message(&self, _msg: msgs::UnsignedGossipMessage) -> Result<Signature, ()> {
+               unreachable!()
+       }
+}
+
 pub struct TestKeysInterface {
        pub backing: keysinterface::PhantomKeysManager,
        pub override_random_bytes: Mutex<Option<[u8; 32]>>,