Use `crate::prelude::*` rather than specific imports
[rust-lightning] / lightning / src / routing / utxo.rs
index 020993f23fb809c250084afe78ec9fad19fbbaad..e775e2628f6ca1df9e497a084506be7dd7eed6eb 100644 (file)
 //! channel matches a UTXO on-chain, requiring at least some marginal on-chain transacting in
 //! order to announce a channel. This module handles that checking.
 
-use bitcoin::{BlockHash, TxOut};
-use bitcoin::hashes::hex::ToHex;
+use bitcoin::TxOut;
+use bitcoin::blockdata::constants::ChainHash;
 
+use hex::DisplayHex;
+
+use crate::events::MessageSendEvent;
 use crate::ln::chan_utils::make_funding_redeemscript_from_slices;
 use crate::ln::msgs::{self, LightningError, ErrorAction};
 use crate::routing::gossip::{NetworkGraph, NodeId, P2PGossipSync};
-use crate::util::events::MessageSendEvent;
 use crate::util::logger::{Level, Logger};
-use crate::util::ser::Writeable;
 
 use crate::prelude::*;
 
 use alloc::sync::{Arc, Weak};
-use crate::sync::Mutex;
+use crate::sync::{Mutex, LockTestExt};
 use core::ops::Deref;
 
 /// An error when accessing the chain via [`UtxoLookup`].
@@ -60,11 +61,11 @@ pub enum UtxoResult {
 /// The `UtxoLookup` trait defines behavior for accessing on-chain UTXOs.
 pub trait UtxoLookup {
        /// Returns the transaction output of a funding transaction encoded by [`short_channel_id`].
-       /// Returns an error if `genesis_hash` is for a different chain or if such a transaction output
-       /// is unknown.
+       /// Returns an error if `chain_hash` is for a different chain or if such a transaction output is
+       /// unknown.
        ///
        /// [`short_channel_id`]: https://github.com/lightning/bolts/blob/master/07-routing-gossip.md#definition-of-short_channel_id
-       fn get_utxo(&self, genesis_hash: &BlockHash, short_channel_id: u64) -> UtxoResult;
+       fn get_utxo(&self, chain_hash: &ChainHash, short_channel_id: u64) -> UtxoResult;
 }
 
 enum ChannelAnnouncement {
@@ -125,9 +126,9 @@ pub struct UtxoFuture {
 
 /// A trivial implementation of [`UtxoLookup`] which is used to call back into the network graph
 /// once we have a concrete resolution of a request.
-struct UtxoResolver(Result<TxOut, UtxoLookupError>);
+pub(crate) struct UtxoResolver(Result<TxOut, UtxoLookupError>);
 impl UtxoLookup for UtxoResolver {
-       fn get_utxo(&self, _genesis_hash: &BlockHash, _short_channel_id: u64) -> UtxoResult {
+       fn get_utxo(&self, _chain_hash: &ChainHash, _short_channel_id: u64) -> UtxoResult {
                UtxoResult::Sync(self.0.clone())
        }
 }
@@ -306,7 +307,7 @@ pub(super) struct PendingChecks {
 impl PendingChecks {
        pub(super) fn new() -> Self {
                PendingChecks { internal: Mutex::new(PendingChecksContext {
-                       channels: HashMap::new(), nodes: HashMap::new(),
+                       channels: new_hash_map(), nodes: new_hash_map(),
                }) }
        }
 
@@ -404,7 +405,10 @@ impl PendingChecks {
                                // lookup if we haven't gotten that far yet).
                                match Weak::upgrade(&e.get()) {
                                        Some(pending_msgs) => {
-                                               let pending_matches = match &pending_msgs.lock().unwrap().channel_announce {
+                                               // This may be called with the mutex held on a different UtxoMessages
+                                               // struct, however in that case we have a global lockorder of new messages
+                                               // -> old messages, which makes this safe.
+                                               let pending_matches = match &pending_msgs.unsafe_well_ordered_double_lock_self().channel_announce {
                                                        Some(ChannelAnnouncement::Full(pending_msg)) => Some(pending_msg) == full_msg,
                                                        Some(ChannelAnnouncement::Unsigned(pending_msg)) => pending_msg == msg,
                                                        None => {
@@ -456,11 +460,11 @@ impl PendingChecks {
                        match res {
                                Ok(TxOut { value, script_pubkey }) => {
                                        let expected_script =
-                                               make_funding_redeemscript_from_slices(msg.bitcoin_key_1.as_slice(), msg.bitcoin_key_2.as_slice()).to_v0_p2wsh();
+                                               make_funding_redeemscript_from_slices(msg.bitcoin_key_1.as_array(), msg.bitcoin_key_2.as_array()).to_v0_p2wsh();
                                        if script_pubkey != expected_script {
                                                return Err(LightningError{
                                                        err: format!("Channel announcement key ({}) didn't match on-chain script ({})",
-                                                               expected_script.to_hex(), script_pubkey.to_hex()),
+                                                               expected_script.to_hex_string(), script_pubkey.to_hex_string()),
                                                        action: ErrorAction::IgnoreError
                                                });
                                        }
@@ -469,7 +473,7 @@ impl PendingChecks {
                                Err(UtxoLookupError::UnknownChain) => {
                                        Err(LightningError {
                                                err: format!("Channel announced on an unknown chain ({})",
-                                                       msg.chain_hash.encode().to_hex()),
+                                                       msg.chain_hash.to_bytes().as_hex()),
                                                action: ErrorAction::IgnoreError
                                        })
                                },
@@ -559,24 +563,21 @@ mod tests {
        use super::*;
        use crate::routing::gossip::tests::*;
        use crate::util::test_utils::{TestChainSource, TestLogger};
-       use crate::ln::msgs;
 
-       use bitcoin::blockdata::constants::genesis_block;
        use bitcoin::secp256k1::{Secp256k1, SecretKey};
 
        use core::sync::atomic::Ordering;
 
        fn get_network() -> (TestChainSource, NetworkGraph<Box<TestLogger>>) {
                let logger = Box::new(TestLogger::new());
-               let genesis_hash = genesis_block(bitcoin::Network::Testnet).header.block_hash();
                let chain_source = TestChainSource::new(bitcoin::Network::Testnet);
-               let network_graph = NetworkGraph::new(genesis_hash, logger);
+               let network_graph = NetworkGraph::new(bitcoin::Network::Testnet, logger);
 
                (chain_source, network_graph)
        }
 
        fn get_test_objects() -> (msgs::ChannelAnnouncement, TestChainSource,
-               NetworkGraph<Box<TestLogger>>, bitcoin::Script, msgs::NodeAnnouncement,
+               NetworkGraph<Box<TestLogger>>, bitcoin::ScriptBuf, msgs::NodeAnnouncement,
                msgs::NodeAnnouncement, msgs::ChannelUpdate, msgs::ChannelUpdate, msgs::ChannelUpdate)
        {
                let secp_ctx = Secp256k1::new();
@@ -659,7 +660,7 @@ mod tests {
                assert!(network_graph.read_only().channels().get(&valid_announcement.contents.short_channel_id).is_none());
 
                future.resolve_without_forwarding(&network_graph,
-                       Ok(TxOut { value: 1_000_000, script_pubkey: bitcoin::Script::new() }));
+                       Ok(TxOut { value: 1_000_000, script_pubkey: bitcoin::ScriptBuf::new() }));
                assert!(network_graph.read_only().channels().get(&valid_announcement.contents.short_channel_id).is_none());
        }
 
@@ -747,10 +748,11 @@ mod tests {
                        Ok(TxOut { value: 1_000_000, script_pubkey: good_script }));
 
                assert_eq!(chan_update_a.contents.timestamp, chan_update_b.contents.timestamp);
-               assert!(network_graph.read_only().channels()
+               let graph_lock = network_graph.read_only();
+               assert!(graph_lock.channels()
                                .get(&valid_announcement.contents.short_channel_id).as_ref().unwrap()
                                .one_to_two.as_ref().unwrap().last_update !=
-                       network_graph.read_only().channels()
+                       graph_lock.channels()
                                .get(&valid_announcement.contents.short_channel_id).as_ref().unwrap()
                                .two_to_one.as_ref().unwrap().last_update);
        }