Merge pull request #823 from jkczyz/2021-03-birthday-hash
authorMatt Corallo <649246+TheBlueMatt@users.noreply.github.com>
Sat, 6 Mar 2021 00:15:05 +0000 (16:15 -0800)
committerGitHub <noreply@github.com>
Sat, 6 Mar 2021 00:15:05 +0000 (16:15 -0800)
Replace default hash with birthday hash

14 files changed:
background-processor/src/lib.rs
fuzz/src/chanmon_consistency.rs
fuzz/src/chanmon_deser.rs
fuzz/src/full_stack.rs
lightning-block-sync/src/init.rs
lightning-persister/src/lib.rs
lightning/src/chain/channelmonitor.rs
lightning/src/ln/chanmon_update_fail_tests.rs
lightning/src/ln/channel.rs
lightning/src/ln/channelmanager.rs
lightning/src/ln/functional_test_utils.rs
lightning/src/ln/functional_tests.rs
lightning/src/ln/reorg_tests.rs
lightning/src/util/test_utils.rs

index 0c7191fbad2bd74fc8ebeafebfe044dbfa97ab96..00f984580f2556fae736a4b7c153caf23839ff58 100644 (file)
@@ -106,7 +106,7 @@ mod tests {
        use lightning::chain::keysinterface::{Sign, InMemorySigner, KeysInterface, KeysManager};
        use lightning::chain::transaction::OutPoint;
        use lightning::get_event_msg;
-       use lightning::ln::channelmanager::{ChannelManager, SimpleArcChannelManager};
+       use lightning::ln::channelmanager::{ChainParameters, ChannelManager, SimpleArcChannelManager};
        use lightning::ln::features::InitFeatures;
        use lightning::ln::msgs::ChannelMessageHandler;
        use lightning::util::config::UserConfig;
@@ -155,10 +155,16 @@ mod tests {
                        let persister = Arc::new(FilesystemPersister::new(format!("{}_persister_{}", persist_dir, i)));
                        let seed = [i as u8; 32];
                        let network = Network::Testnet;
-                       let now = Duration::from_secs(genesis_block(network).header.time as u64);
+                       let genesis_block = genesis_block(network);
+                       let now = Duration::from_secs(genesis_block.header.time as u64);
                        let keys_manager = Arc::new(KeysManager::new(&seed, now.as_secs(), now.subsec_nanos()));
                        let chain_monitor = Arc::new(chainmonitor::ChainMonitor::new(Some(chain_source.clone()), tx_broadcaster.clone(), logger.clone(), fee_estimator.clone(), persister.clone()));
-                       let manager = Arc::new(ChannelManager::new(Network::Testnet, fee_estimator.clone(), chain_monitor.clone(), tx_broadcaster, logger.clone(), keys_manager.clone(), UserConfig::default(), i));
+                       let params = ChainParameters {
+                               network,
+                               latest_hash: genesis_block.block_hash(),
+                               latest_height: 0,
+                       };
+                       let manager = Arc::new(ChannelManager::new(fee_estimator.clone(), chain_monitor.clone(), tx_broadcaster, logger.clone(), keys_manager.clone(), UserConfig::default(), params));
                        let node = Node { node: manager, persister, logger };
                        nodes.push(node);
                }
index dcf8c31ffb771a83a3db6d59ec3871d86a93ebc2..3e205c07183d402fe045110d562f94b084224155 100644 (file)
@@ -19,6 +19,7 @@
 //! channel being force-closed.
 
 use bitcoin::blockdata::block::BlockHeader;
+use bitcoin::blockdata::constants::genesis_block;
 use bitcoin::blockdata::transaction::{Transaction, TxOut};
 use bitcoin::blockdata::script::{Builder, Script};
 use bitcoin::blockdata::opcodes;
@@ -35,7 +36,7 @@ use lightning::chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdateErr,
 use lightning::chain::transaction::OutPoint;
 use lightning::chain::chaininterface::{BroadcasterInterface, ConfirmationTarget, FeeEstimator};
 use lightning::chain::keysinterface::{KeysInterface, InMemorySigner};
-use lightning::ln::channelmanager::{ChannelManager, PaymentHash, PaymentPreimage, PaymentSecret, PaymentSendFailure, ChannelManagerReadArgs};
+use lightning::ln::channelmanager::{ChainParameters, ChannelManager, PaymentHash, PaymentPreimage, PaymentSecret, PaymentSendFailure, ChannelManagerReadArgs};
 use lightning::ln::features::{ChannelFeatures, InitFeatures, NodeFeatures};
 use lightning::ln::msgs::{CommitmentUpdate, ChannelMessageHandler, DecodeError, ErrorAction, UpdateAddHTLC, Init};
 use lightning::util::enforcing_trait_impls::{EnforcingSigner, INITIAL_REVOKED_COMMITMENT_NUMBER};
@@ -126,7 +127,7 @@ impl chain::Watch<EnforcingSigner> for TestChainMonitor {
                        hash_map::Entry::Occupied(entry) => entry,
                        hash_map::Entry::Vacant(_) => panic!("Didn't have monitor on update call"),
                };
-               let deserialized_monitor = <(Option<BlockHash>, channelmonitor::ChannelMonitor<EnforcingSigner>)>::
+               let deserialized_monitor = <(BlockHash, channelmonitor::ChannelMonitor<EnforcingSigner>)>::
                        read(&mut Cursor::new(&map_entry.get().1), &OnlyReadsKeysInterface {}).unwrap().1;
                deserialized_monitor.update_monitor(&update, &&TestBroadcaster{}, &&FuzzEstimator{}, &self.logger).unwrap();
                let mut ser = VecWriter(Vec::new());
@@ -318,7 +319,13 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
                        config.channel_options.fee_proportional_millionths = 0;
                        config.channel_options.announced_channel = true;
                        config.peer_channel_config_limits.min_dust_limit_satoshis = 0;
-                       (ChannelManager::new(Network::Bitcoin, fee_est.clone(), monitor.clone(), broadcast.clone(), Arc::clone(&logger), keys_manager.clone(), config, 0),
+                       let network = Network::Bitcoin;
+                       let params = ChainParameters {
+                               network,
+                               latest_hash: genesis_block(network).block_hash(),
+                               latest_height: 0,
+                       };
+                       (ChannelManager::new(fee_est.clone(), monitor.clone(), broadcast.clone(), Arc::clone(&logger), keys_manager.clone(), config, params),
                        monitor, keys_manager)
                } }
        }
@@ -337,7 +344,7 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
                        let mut monitors = HashMap::new();
                        let mut old_monitors = $old_monitors.latest_monitors.lock().unwrap();
                        for (outpoint, (update_id, monitor_ser)) in old_monitors.drain() {
-                               monitors.insert(outpoint, <(Option<BlockHash>, ChannelMonitor<EnforcingSigner>)>::read(&mut Cursor::new(&monitor_ser), &OnlyReadsKeysInterface {}).expect("Failed to read monitor").1);
+                               monitors.insert(outpoint, <(BlockHash, ChannelMonitor<EnforcingSigner>)>::read(&mut Cursor::new(&monitor_ser), &OnlyReadsKeysInterface {}).expect("Failed to read monitor").1);
                                chain_monitor.latest_monitors.lock().unwrap().insert(outpoint, (update_id, monitor_ser));
                        }
                        let mut monitor_refs = HashMap::new();
@@ -355,7 +362,7 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
                                channel_monitors: monitor_refs,
                        };
 
-                       (<(Option<BlockHash>, ChanMan)>::read(&mut Cursor::new(&$ser.0), read_args).expect("Failed to read manager").1, chain_monitor)
+                       (<(BlockHash, ChanMan)>::read(&mut Cursor::new(&$ser.0), read_args).expect("Failed to read manager").1, chain_monitor)
                } }
        }
 
index e7dbf3ed8d6a588aef5e7529d7295999018d01ca..933930cf6d163148cb28832fde7cbcf47133b90b 100644 (file)
@@ -25,13 +25,11 @@ impl Writer for VecWriter {
 
 #[inline]
 pub fn do_test<Out: test_logger::Output>(data: &[u8], _out: Out) {
-       if let Ok((Some(latest_block_hash), monitor)) = <(Option<BlockHash>, channelmonitor::ChannelMonitor<EnforcingSigner>)>::read(&mut Cursor::new(data), &OnlyReadsKeysInterface {}) {
+       if let Ok((latest_block_hash, monitor)) = <(BlockHash, channelmonitor::ChannelMonitor<EnforcingSigner>)>::read(&mut Cursor::new(data), &OnlyReadsKeysInterface {}) {
                let mut w = VecWriter(Vec::new());
                monitor.write(&mut w).unwrap();
-               let deserialized_copy = <(Option<BlockHash>, channelmonitor::ChannelMonitor<EnforcingSigner>)>::read(&mut Cursor::new(&w.0), &OnlyReadsKeysInterface {}).unwrap();
-               if let Some(deserialized) = deserialized_copy.0 {
-                       assert!(latest_block_hash == deserialized);
-               }
+               let deserialized_copy = <(BlockHash, channelmonitor::ChannelMonitor<EnforcingSigner>)>::read(&mut Cursor::new(&w.0), &OnlyReadsKeysInterface {}).unwrap();
+               assert!(latest_block_hash == deserialized_copy.0);
                assert!(monitor == deserialized_copy.1);
        }
 }
index 3774d0dce839848cb7034fbf041da52c78e60142..132ff95f6bbb6ccafe1f18a893f05b625ad4120c 100644 (file)
@@ -31,7 +31,7 @@ use lightning::chain::chaininterface::{BroadcasterInterface, ConfirmationTarget,
 use lightning::chain::chainmonitor;
 use lightning::chain::transaction::OutPoint;
 use lightning::chain::keysinterface::{InMemorySigner, KeysInterface};
-use lightning::ln::channelmanager::{ChannelManager, PaymentHash, PaymentPreimage, PaymentSecret};
+use lightning::ln::channelmanager::{ChainParameters, ChannelManager, PaymentHash, PaymentPreimage, PaymentSecret};
 use lightning::ln::peer_handler::{MessageHandler,PeerManager,SocketDescriptor};
 use lightning::ln::msgs::DecodeError;
 use lightning::routing::router::get_route;
@@ -348,9 +348,16 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
        config.channel_options.fee_proportional_millionths =  slice_to_be32(get_slice!(4));
        config.channel_options.announced_channel = get_slice!(1)[0] != 0;
        config.peer_channel_config_limits.min_dust_limit_satoshis = 0;
-       let channelmanager = Arc::new(ChannelManager::new(Network::Bitcoin, fee_est.clone(), monitor.clone(), broadcast.clone(), Arc::clone(&logger), keys_manager.clone(), config, 0));
+       let network = Network::Bitcoin;
+       let genesis_hash = genesis_block(network).block_hash();
+       let params = ChainParameters {
+               network,
+               latest_hash: genesis_hash,
+               latest_height: 0,
+       };
+       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 net_graph_msg_handler = Arc::new(NetGraphMsgHandler::new(genesis_block(Network::Bitcoin).header.block_hash(), None, Arc::clone(&logger)));
+       let net_graph_msg_handler = Arc::new(NetGraphMsgHandler::new(genesis_hash, None, Arc::clone(&logger)));
 
        let peers = RefCell::new([false; 256]);
        let mut loss_detector = MoneyLossDetector::new(&peers, channelmanager.clone(), monitor.clone(), PeerManager::new(MessageHandler {
index 59c057157ef14bd6332d0bad1c2207b2919e741c..83e356919b8e231a8d4a3bda41b0d65645e146fc 100644 (file)
@@ -73,12 +73,12 @@ BlockSourceResult<ValidatedBlockHeader> {
 /// ) {
 ///    // Read a serialized channel monitor paired with the block hash when it was persisted.
 ///    let serialized_monitor = "...";
-///    let (monitor_block_hash_option, mut monitor) = <(Option<BlockHash>, ChannelMonitor<S>)>::read(
+///    let (monitor_block_hash, mut monitor) = <(BlockHash, ChannelMonitor<S>)>::read(
 ///            &mut Cursor::new(&serialized_monitor), keys_manager).unwrap();
 ///
 ///    // Read the channel manager paired with the block hash when it was persisted.
 ///    let serialized_manager = "...";
-///    let (manager_block_hash_option, mut manager) = {
+///    let (manager_block_hash, mut manager) = {
 ///            let read_args = ChannelManagerReadArgs::new(
 ///                    keys_manager,
 ///                    fee_estimator,
@@ -88,20 +88,17 @@ BlockSourceResult<ValidatedBlockHeader> {
 ///                    config,
 ///                    vec![&mut monitor],
 ///            );
-///            <(Option<BlockHash>, ChannelManager<S, &ChainMonitor<S, &C, &T, &F, &L, &P>, &T, &K, &F, &L>)>::read(
+///            <(BlockHash, ChannelManager<S, &ChainMonitor<S, &C, &T, &F, &L, &P>, &T, &K, &F, &L>)>::read(
 ///                    &mut Cursor::new(&serialized_manager), read_args).unwrap()
 ///    };
 ///
 ///    // Synchronize any channel monitors and the channel manager to be on the best block.
 ///    let mut cache = UnboundedCache::new();
 ///    let mut monitor_listener = (monitor, &*tx_broadcaster, &*fee_estimator, &*logger);
-///    let mut listeners = vec![];
-///    if let Some(monitor_block_hash) = monitor_block_hash_option {
-///            listeners.push((monitor_block_hash, &mut monitor_listener as &mut dyn chain::Listen))
-///    }
-///    if let Some(manager_block_hash) = manager_block_hash_option {
-///            listeners.push((manager_block_hash, &mut manager as &mut dyn chain::Listen))
-///    }
+///    let listeners = vec![
+///            (monitor_block_hash, &mut monitor_listener as &mut dyn chain::Listen),
+///            (manager_block_hash, &mut manager as &mut dyn chain::Listen),
+///    ];
 ///    let chain_tip = init::synchronize_listeners(
 ///            block_source, Network::Bitcoin, &mut cache, listeners).await.unwrap();
 ///
index 0151b1e464ea6af8559e147ef19084331485f8f9..2226bcba6095373f7ae3dc2f7b3db2f7cf5e034c 100644 (file)
@@ -124,7 +124,7 @@ impl FilesystemPersister {
                                if contents.is_err() { return Err(ChannelMonitorUpdateErr::PermanentFailure); }
 
                                if let Ok((_, loaded_monitor)) =
-                                       <(Option<BlockHash>, ChannelMonitor<Keys::Signer>)>::read(&mut Cursor::new(&contents.unwrap()), keys) {
+                                       <(BlockHash, ChannelMonitor<Keys::Signer>)>::read(&mut Cursor::new(&contents.unwrap()), keys) {
                                                res.insert(OutPoint { txid: txid.unwrap(), index: index.unwrap() }, loaded_monitor);
                                        } else {
                                                return Err(ChannelMonitorUpdateErr::PermanentFailure);
index 4d2d1b848aecb187471c203e1f962675a37fdbf8..2352661271f46d8f48bb35703b6e1579951381dd 100644 (file)
@@ -620,7 +620,7 @@ impl Readable for ChannelMonitorUpdateStep {
 /// reloaded at deserialize-time. Thus, you must ensure that, when handling events, all events
 /// gotten are fully handled before re-serializing the new state.
 ///
-/// Note that the deserializer is only implemented for (Option<BlockHash>, ChannelMonitor), which
+/// Note that the deserializer is only implemented for (BlockHash, ChannelMonitor), which
 /// tells you the last block hash which was block_connect()ed. You MUST rescan any blocks along
 /// the "reorg path" (ie disconnecting blocks until you find a common ancestor from both the
 /// returned block hash and the the current chain and then reconnecting blocks to get to the
@@ -980,7 +980,8 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
                          channel_parameters: &ChannelTransactionParameters,
                          funding_redeemscript: Script, channel_value_satoshis: u64,
                          commitment_transaction_number_obscure_factor: u64,
-                         initial_holder_commitment_tx: HolderCommitmentTransaction) -> ChannelMonitor<Signer> {
+                         initial_holder_commitment_tx: HolderCommitmentTransaction,
+                         last_block_hash: BlockHash) -> ChannelMonitor<Signer> {
 
                assert!(commitment_transaction_number_obscure_factor <= (1 << 48));
                let our_channel_close_key_hash = WPubkeyHash::hash(&shutdown_pubkey.serialize());
@@ -1067,7 +1068,7 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
                                lockdown_from_offchain: false,
                                holder_tx_signed: false,
 
-                               last_block_hash: Default::default(),
+                               last_block_hash,
                                secp_ctx,
                        }),
                }
@@ -2089,8 +2090,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
                      F::Target: FeeEstimator,
                      L::Target: Logger,
        {
-               let block_hash = header.block_hash();
-               log_trace!(logger, "Block {} at height {} disconnected", block_hash, height);
+               log_trace!(logger, "Block {} at height {} disconnected", header.block_hash(), height);
 
                if let Some(_) = self.onchain_events_waiting_threshold_conf.remove(&(height + ANTI_REORG_DELAY - 1)) {
                        //We may discard:
@@ -2100,7 +2100,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
 
                self.onchain_tx_handler.block_disconnected(height, broadcaster, fee_estimator, logger);
 
-               self.last_block_hash = block_hash;
+               self.last_block_hash = header.prev_blockhash;
        }
 
        /// Filters a block's `txdata` for transactions spending watched outputs or for any child
@@ -2492,7 +2492,7 @@ where
 const MAX_ALLOC_SIZE: usize = 64*1024;
 
 impl<'a, Signer: Sign, K: KeysInterface<Signer = Signer>> ReadableArgs<&'a K>
-               for (Option<BlockHash>, ChannelMonitor<Signer>) {
+               for (BlockHash, ChannelMonitor<Signer>) {
        fn read<R: ::std::io::Read>(reader: &mut R, keys_manager: &'a K) -> Result<Self, DecodeError> {
                macro_rules! unwrap_obj {
                        ($key: expr) => {
@@ -2735,13 +2735,7 @@ impl<'a, Signer: Sign, K: KeysInterface<Signer = Signer>> ReadableArgs<&'a K>
                let mut secp_ctx = Secp256k1::new();
                secp_ctx.seeded_randomize(&keys_manager.get_secure_random_bytes());
 
-               let last_seen_block_hash = if last_block_hash == Default::default() {
-                       None
-               } else {
-                       Some(last_block_hash)
-               };
-
-               Ok((last_seen_block_hash, ChannelMonitor {
+               Ok((last_block_hash.clone(), ChannelMonitor {
                        inner: Mutex::new(ChannelMonitorImpl {
                                latest_update_id,
                                commitment_transaction_number_obscure_factor,
@@ -2795,6 +2789,7 @@ impl<'a, Signer: Sign, K: KeysInterface<Signer = Signer>> ReadableArgs<&'a K>
 
 #[cfg(test)]
 mod tests {
+       use bitcoin::blockdata::constants::genesis_block;
        use bitcoin::blockdata::script::{Script, Builder};
        use bitcoin::blockdata::opcodes;
        use bitcoin::blockdata::transaction::{Transaction, TxIn, TxOut, SigHashType};
@@ -2804,6 +2799,7 @@ mod tests {
        use bitcoin::hashes::sha256::Hash as Sha256;
        use bitcoin::hashes::hex::FromHex;
        use bitcoin::hash_types::Txid;
+       use bitcoin::network::constants::Network;
        use hex;
        use chain::channelmonitor::ChannelMonitor;
        use chain::transaction::OutPoint;
@@ -2903,12 +2899,13 @@ mod tests {
                };
                // Prune with one old state and a holder commitment tx holding a few overlaps with the
                // old state.
+               let last_block_hash = genesis_block(Network::Testnet).block_hash();
                let monitor = ChannelMonitor::new(Secp256k1::new(), keys,
                                                  &PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap()), 0, &Script::new(),
                                                  (OutPoint { txid: Txid::from_slice(&[43; 32]).unwrap(), index: 0 }, Script::new()),
                                                  &channel_parameters,
                                                  Script::new(), 46, 0,
-                                                 HolderCommitmentTransaction::dummy());
+                                                 HolderCommitmentTransaction::dummy(), last_block_hash);
 
                monitor.provide_latest_holder_commitment_tx(HolderCommitmentTransaction::dummy(), preimages_to_holder_htlcs!(preimages[0..10])).unwrap();
                let dummy_txid = dummy_tx.txid();
index 3ed84de95ae493f355abab0fb57cd57b6b01cf8d..d764bc782152e5170f434060226d412c4156c916 100644 (file)
@@ -106,7 +106,7 @@ fn test_monitor_and_persister_update_fail() {
                let monitor = monitors.get(&outpoint).unwrap();
                let mut w = test_utils::TestVecWriter(Vec::new());
                monitor.write(&mut w).unwrap();
-               let new_monitor = <(Option<BlockHash>, ChannelMonitor<EnforcingSigner>)>::read(
+               let new_monitor = <(BlockHash, ChannelMonitor<EnforcingSigner>)>::read(
                        &mut ::std::io::Cursor::new(&w.0), &test_utils::OnlyReadsKeysInterface {}).unwrap().1;
                assert!(new_monitor == *monitor);
                let chain_mon = test_utils::TestChainMonitor::new(Some(&chain_source), &chanmon_cfgs[0].tx_broadcaster, &logger, &chanmon_cfgs[0].fee_estimator, &persister, &node_cfgs[0].keys_manager);
index a5f4b16e6a1a1b5b05bc1b0c49a1fac1cdfd8438..9e4bb081c1a98ddc5bd17c4b818a835a37f10a65 100644 (file)
@@ -39,7 +39,6 @@ use util::errors::APIError;
 use util::config::{UserConfig,ChannelConfig};
 
 use std;
-use std::default::Default;
 use std::{cmp,mem,fmt};
 use std::ops::Deref;
 #[cfg(any(test, feature = "fuzztarget"))]
@@ -368,9 +367,6 @@ pub(super) struct Channel<Signer: Sign> {
        /// could miss the funding_tx_confirmed_in block as well, but it serves as a useful fallback.
        funding_tx_confirmed_in: Option<BlockHash>,
        short_channel_id: Option<u64>,
-       /// Used to deduplicate block_connected callbacks, also used to verify consistency during
-       /// ChannelManager deserialization (hence pub(super))
-       pub(super) last_block_connected: BlockHash,
        funding_tx_confirmations: u64,
 
        counterparty_dust_limit_satoshis: u64,
@@ -569,7 +565,6 @@ impl<Signer: Sign> Channel<Signer> {
 
                        funding_tx_confirmed_in: None,
                        short_channel_id: None,
-                       last_block_connected: Default::default(),
                        funding_tx_confirmations: 0,
 
                        feerate_per_kw: feerate,
@@ -805,7 +800,6 @@ impl<Signer: Sign> Channel<Signer> {
 
                        funding_tx_confirmed_in: None,
                        short_channel_id: None,
-                       last_block_connected: Default::default(),
                        funding_tx_confirmations: 0,
 
                        feerate_per_kw: msg.feerate_per_kw,
@@ -1522,7 +1516,7 @@ impl<Signer: Sign> Channel<Signer> {
                &self.get_counterparty_pubkeys().funding_pubkey
        }
 
-       pub fn funding_created<L: Deref>(&mut self, msg: &msgs::FundingCreated, logger: &L) -> Result<(msgs::FundingSigned, ChannelMonitor<Signer>), ChannelError> where L::Target: Logger {
+       pub fn funding_created<L: Deref>(&mut self, msg: &msgs::FundingCreated, last_block_hash: BlockHash, logger: &L) -> Result<(msgs::FundingSigned, ChannelMonitor<Signer>), ChannelError> where L::Target: Logger {
                if self.is_outbound() {
                        return Err(ChannelError::Close("Received funding_created for an outbound channel?".to_owned()));
                }
@@ -1576,7 +1570,7 @@ impl<Signer: Sign> Channel<Signer> {
                                                          &self.channel_transaction_parameters,
                                                          funding_redeemscript.clone(), self.channel_value_satoshis,
                                                          obscure_factor,
-                                                         holder_commitment_tx);
+                                                         holder_commitment_tx, last_block_hash);
 
                channel_monitor.provide_latest_counterparty_commitment_tx(counterparty_initial_commitment_txid, Vec::new(), self.cur_counterparty_commitment_transaction_number, self.counterparty_cur_commitment_point.unwrap(), logger);
 
@@ -1593,7 +1587,7 @@ impl<Signer: Sign> Channel<Signer> {
 
        /// Handles a funding_signed message from the remote end.
        /// If this call is successful, broadcast the funding transaction (and not before!)
-       pub fn funding_signed<L: Deref>(&mut self, msg: &msgs::FundingSigned, logger: &L) -> Result<ChannelMonitor<Signer>, ChannelError> where L::Target: Logger {
+       pub fn funding_signed<L: Deref>(&mut self, msg: &msgs::FundingSigned, last_block_hash: BlockHash, logger: &L) -> Result<ChannelMonitor<Signer>, ChannelError> where L::Target: Logger {
                if !self.is_outbound() {
                        return Err(ChannelError::Close("Received funding_signed for an inbound channel?".to_owned()));
                }
@@ -1646,7 +1640,7 @@ impl<Signer: Sign> Channel<Signer> {
                                                          &self.channel_transaction_parameters,
                                                          funding_redeemscript.clone(), self.channel_value_satoshis,
                                                          obscure_factor,
-                                                         holder_commitment_tx);
+                                                         holder_commitment_tx, last_block_hash);
 
                channel_monitor.provide_latest_counterparty_commitment_tx(counterparty_initial_bitcoin_tx.txid, Vec::new(), self.cur_counterparty_commitment_transaction_number, self.counterparty_cur_commitment_point.unwrap(), logger);
 
@@ -3517,12 +3511,12 @@ impl<Signer: Sign> Channel<Signer> {
                                _ => true
                        }
                });
-               let non_shutdown_state = self.channel_state & (!MULTI_STATE_FLAGS);
-               if header.block_hash() != self.last_block_connected {
-                       if self.funding_tx_confirmations > 0 {
-                               self.funding_tx_confirmations += 1;
-                       }
+
+               if self.funding_tx_confirmations > 0 {
+                       self.funding_tx_confirmations += 1;
                }
+
+               let non_shutdown_state = self.channel_state & (!MULTI_STATE_FLAGS);
                if non_shutdown_state & !(ChannelState::TheirFundingLocked as u32) == ChannelState::FundingSent as u32 {
                        for &(index_in_block, tx) in txdata.iter() {
                                let funding_txo = self.get_funding_txo().unwrap();
@@ -3568,46 +3562,44 @@ impl<Signer: Sign> Channel<Signer> {
                                }
                        }
                }
-               if header.block_hash() != self.last_block_connected {
-                       self.last_block_connected = header.block_hash();
-                       self.update_time_counter = cmp::max(self.update_time_counter, header.time);
-                       if self.funding_tx_confirmations > 0 {
-                               if self.funding_tx_confirmations == self.minimum_depth as u64 {
-                                       let need_commitment_update = if non_shutdown_state == ChannelState::FundingSent as u32 {
-                                               self.channel_state |= ChannelState::OurFundingLocked as u32;
-                                               true
-                                       } else if non_shutdown_state == (ChannelState::FundingSent as u32 | ChannelState::TheirFundingLocked as u32) {
-                                               self.channel_state = ChannelState::ChannelFunded as u32 | (self.channel_state & MULTI_STATE_FLAGS);
-                                               self.update_time_counter += 1;
-                                               true
-                                       } else if non_shutdown_state == (ChannelState::FundingSent as u32 | ChannelState::OurFundingLocked as u32) {
-                                               // We got a reorg but not enough to trigger a force close, just update
-                                               // funding_tx_confirmed_in and return.
-                                               false
-                                       } else if self.channel_state < ChannelState::ChannelFunded as u32 {
-                                               panic!("Started confirming a channel in a state pre-FundingSent?: {}", self.channel_state);
+
+               self.update_time_counter = cmp::max(self.update_time_counter, header.time);
+               if self.funding_tx_confirmations > 0 {
+                       if self.funding_tx_confirmations == self.minimum_depth as u64 {
+                               let need_commitment_update = if non_shutdown_state == ChannelState::FundingSent as u32 {
+                                       self.channel_state |= ChannelState::OurFundingLocked as u32;
+                                       true
+                               } else if non_shutdown_state == (ChannelState::FundingSent as u32 | ChannelState::TheirFundingLocked as u32) {
+                                       self.channel_state = ChannelState::ChannelFunded as u32 | (self.channel_state & MULTI_STATE_FLAGS);
+                                       self.update_time_counter += 1;
+                                       true
+                               } else if non_shutdown_state == (ChannelState::FundingSent as u32 | ChannelState::OurFundingLocked as u32) {
+                                       // We got a reorg but not enough to trigger a force close, just update
+                                       // funding_tx_confirmed_in and return.
+                                       false
+                               } else if self.channel_state < ChannelState::ChannelFunded as u32 {
+                                       panic!("Started confirming a channel in a state pre-FundingSent?: {}", self.channel_state);
+                               } else {
+                                       // We got a reorg but not enough to trigger a force close, just update
+                                       // funding_tx_confirmed_in and return.
+                                       false
+                               };
+                               self.funding_tx_confirmed_in = Some(header.block_hash());
+
+                               //TODO: Note that this must be a duplicate of the previous commitment point they sent us,
+                               //as otherwise we will have a commitment transaction that they can't revoke (well, kinda,
+                               //they can by sending two revoke_and_acks back-to-back, but not really). This appears to be
+                               //a protocol oversight, but I assume I'm just missing something.
+                               if need_commitment_update {
+                                       if self.channel_state & (ChannelState::MonitorUpdateFailed as u32) == 0 {
+                                               let next_per_commitment_point = self.holder_signer.get_per_commitment_point(self.cur_holder_commitment_transaction_number, &self.secp_ctx);
+                                               return Ok((Some(msgs::FundingLocked {
+                                                       channel_id: self.channel_id,
+                                                       next_per_commitment_point,
+                                               }), timed_out_htlcs));
                                        } else {
-                                               // We got a reorg but not enough to trigger a force close, just update
-                                               // funding_tx_confirmed_in and return.
-                                               false
-                                       };
-                                       self.funding_tx_confirmed_in = Some(self.last_block_connected);
-
-                                       //TODO: Note that this must be a duplicate of the previous commitment point they sent us,
-                                       //as otherwise we will have a commitment transaction that they can't revoke (well, kinda,
-                                       //they can by sending two revoke_and_acks back-to-back, but not really). This appears to be
-                                       //a protocol oversight, but I assume I'm just missing something.
-                                       if need_commitment_update {
-                                               if self.channel_state & (ChannelState::MonitorUpdateFailed as u32) == 0 {
-                                                       let next_per_commitment_point = self.holder_signer.get_per_commitment_point(self.cur_holder_commitment_transaction_number, &self.secp_ctx);
-                                                       return Ok((Some(msgs::FundingLocked {
-                                                               channel_id: self.channel_id,
-                                                               next_per_commitment_point,
-                                                       }), timed_out_htlcs));
-                                               } else {
-                                                       self.monitor_pending_funding_locked = true;
-                                                       return Ok((None, timed_out_htlcs));
-                                               }
+                                               self.monitor_pending_funding_locked = true;
+                                               return Ok((None, timed_out_htlcs));
                                        }
                                }
                        }
@@ -3625,8 +3617,7 @@ impl<Signer: Sign> Channel<Signer> {
                                return true;
                        }
                }
-               self.last_block_connected = header.block_hash();
-               if Some(self.last_block_connected) == self.funding_tx_confirmed_in {
+               if Some(header.block_hash()) == self.funding_tx_confirmed_in {
                        self.funding_tx_confirmations = self.minimum_depth as u64 - 1;
                }
                false
@@ -4435,8 +4426,6 @@ impl<Signer: Sign> Writeable for Channel<Signer> {
 
                self.funding_tx_confirmed_in.write(writer)?;
                self.short_channel_id.write(writer)?;
-
-               self.last_block_connected.write(writer)?;
                self.funding_tx_confirmations.write(writer)?;
 
                self.counterparty_dust_limit_satoshis.write(writer)?;
@@ -4597,8 +4586,6 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<&'a K> for Channel<Signer>
 
                let funding_tx_confirmed_in = Readable::read(reader)?;
                let short_channel_id = Readable::read(reader)?;
-
-               let last_block_connected = Readable::read(reader)?;
                let funding_tx_confirmations = Readable::read(reader)?;
 
                let counterparty_dust_limit_satoshis = Readable::read(reader)?;
@@ -4669,7 +4656,6 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<&'a K> for Channel<Signer>
 
                        funding_tx_confirmed_in,
                        short_channel_id,
-                       last_block_connected,
                        funding_tx_confirmations,
 
                        counterparty_dust_limit_satoshis,
@@ -4924,6 +4910,8 @@ mod tests {
                let secp_ctx = Secp256k1::new();
                let seed = [42; 32];
                let network = Network::Testnet;
+               let chain_hash = genesis_block(network).header.block_hash();
+               let last_block_hash = chain_hash;
                let keys_provider = test_utils::TestKeysInterface::new(&seed, network);
 
                // Go through the flow of opening a channel between two nodes.
@@ -4934,7 +4922,7 @@ mod tests {
                let mut node_a_chan = Channel::<EnforcingSigner>::new_outbound(&&feeest, &&keys_provider, node_b_node_id, 10000000, 100000, 42, &config).unwrap();
 
                // Create Node B's channel by receiving Node A's open_channel message
-               let open_channel_msg = node_a_chan.get_open_channel(genesis_block(network).header.block_hash());
+               let open_channel_msg = node_a_chan.get_open_channel(chain_hash);
                let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[7; 32]).unwrap());
                let mut node_b_chan = Channel::<EnforcingSigner>::new_from_req(&&feeest, &&keys_provider, node_b_node_id, InitFeatures::known(), &open_channel_msg, 7, &config).unwrap();
 
@@ -4949,10 +4937,10 @@ mod tests {
                }]};
                let funding_outpoint = OutPoint{ txid: tx.txid(), index: 0 };
                let funding_created_msg = node_a_chan.get_outbound_funding_created(funding_outpoint, &&logger).unwrap();
-               let (funding_signed_msg, _) = node_b_chan.funding_created(&funding_created_msg, &&logger).unwrap();
+               let (funding_signed_msg, _) = node_b_chan.funding_created(&funding_created_msg, last_block_hash, &&logger).unwrap();
 
                // Node B --> Node A: funding signed
-               let _ = node_a_chan.funding_signed(&funding_signed_msg, &&logger);
+               let _ = node_a_chan.funding_signed(&funding_signed_msg, last_block_hash, &&logger);
 
                // Now disconnect the two nodes and check that the commitment point in
                // Node B's channel_reestablish message is sane.
index 86ccc03bab6545b84ad193222671316f459e1cc4..6e46d79fb08a76624e57bb2b25bac77834941be3 100644 (file)
@@ -389,7 +389,7 @@ pub type SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, M, T, F, L> = ChannelManage
 /// ChannelMonitors passed by reference to read(), those channels will be force-closed based on the
 /// ChannelMonitor state and no funds will be lost (mod on-chain transaction fees).
 ///
-/// Note that the deserializer is only implemented for (Option<BlockHash>, ChannelManager), which
+/// Note that the deserializer is only implemented for (BlockHash, ChannelManager), which
 /// tells you the last block hash which was block_connect()ed. You MUST rescan any blocks along
 /// the "reorg path" (ie call block_disconnected() until you get to a common block and then call
 /// block_connected() to step towards your best block) upon deserialization before using the
@@ -423,7 +423,7 @@ pub struct ChannelManager<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref,
        pub(super) latest_block_height: AtomicUsize,
        #[cfg(not(test))]
        latest_block_height: AtomicUsize,
-       last_block_hash: Mutex<BlockHash>,
+       last_block_hash: RwLock<BlockHash>,
        secp_ctx: Secp256k1<secp256k1::All>,
 
        #[cfg(any(test, feature = "_test_utils"))]
@@ -461,6 +461,24 @@ pub struct ChannelManager<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref,
        logger: L,
 }
 
+/// Chain-related parameters used to construct a new `ChannelManager`.
+///
+/// Typically, the block-specific parameters are derived from the best block hash for the network,
+/// as a newly constructed `ChannelManager` will not have created any channels yet. These parameters
+/// are not needed when deserializing a previously constructed `ChannelManager`.
+pub struct ChainParameters {
+       /// The network for determining the `chain_hash` in Lightning messages.
+       pub network: Network,
+
+       /// The hash of the latest block successfully connected.
+       pub latest_hash: BlockHash,
+
+       /// The height of the latest block successfully connected.
+       ///
+       /// Used to track on-chain channel funding outputs and send payments with reliable timelocks.
+       pub latest_height: usize,
+}
+
 /// Whenever we release the `ChannelManager`'s `total_consistency_lock`, from read mode, it is
 /// desirable to notify any listeners on `wait_timeout`/`wait` that new updates are available for
 /// persistence. Therefore, this struct is responsible for locking the total consistency lock and,
@@ -770,24 +788,22 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
        ///
        /// panics if channel_value_satoshis is >= `MAX_FUNDING_SATOSHIS`!
        ///
-       /// Users must provide the current blockchain height from which to track onchain channel
-       /// funding outpoints and send payments with reliable timelocks.
-       ///
        /// Users need to notify the new ChannelManager when a new block is connected or
-       /// disconnected using its `block_connected` and `block_disconnected` methods.
-       pub fn new(network: Network, fee_est: F, chain_monitor: M, tx_broadcaster: T, logger: L, keys_manager: K, config: UserConfig, current_blockchain_height: usize) -> Self {
+       /// disconnected using its `block_connected` and `block_disconnected` methods, starting
+       /// from after `params.latest_hash`.
+       pub fn new(fee_est: F, chain_monitor: M, tx_broadcaster: T, logger: L, keys_manager: K, config: UserConfig, params: ChainParameters) -> Self {
                let mut secp_ctx = Secp256k1::new();
                secp_ctx.seeded_randomize(&keys_manager.get_secure_random_bytes());
 
                ChannelManager {
                        default_configuration: config.clone(),
-                       genesis_hash: genesis_block(network).header.block_hash(),
+                       genesis_hash: genesis_block(params.network).header.block_hash(),
                        fee_estimator: fee_est,
                        chain_monitor,
                        tx_broadcaster,
 
-                       latest_block_height: AtomicUsize::new(current_blockchain_height),
-                       last_block_hash: Mutex::new(Default::default()),
+                       latest_block_height: AtomicUsize::new(params.latest_height),
+                       last_block_hash: RwLock::new(params.latest_hash),
                        secp_ctx,
 
                        channel_state: Mutex::new(ChannelHolder{
@@ -2438,6 +2454,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
 
        fn internal_funding_created(&self, counterparty_node_id: &PublicKey, msg: &msgs::FundingCreated) -> Result<(), MsgHandleErrInternal> {
                let ((funding_msg, monitor), mut chan) = {
+                       let last_block_hash = *self.last_block_hash.read().unwrap();
                        let mut channel_lock = self.channel_state.lock().unwrap();
                        let channel_state = &mut *channel_lock;
                        match channel_state.by_id.entry(msg.temporary_channel_id.clone()) {
@@ -2445,7 +2462,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                        if chan.get().get_counterparty_node_id() != *counterparty_node_id {
                                                return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!".to_owned(), msg.temporary_channel_id));
                                        }
-                                       (try_chan_entry!(self, chan.get_mut().funding_created(msg, &self.logger), channel_state, chan), chan.remove())
+                                       (try_chan_entry!(self, chan.get_mut().funding_created(msg, last_block_hash, &self.logger), channel_state, chan), chan.remove())
                                },
                                hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel".to_owned(), msg.temporary_channel_id))
                        }
@@ -2494,6 +2511,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
 
        fn internal_funding_signed(&self, counterparty_node_id: &PublicKey, msg: &msgs::FundingSigned) -> Result<(), MsgHandleErrInternal> {
                let (funding_txo, user_id) = {
+                       let last_block_hash = *self.last_block_hash.read().unwrap();
                        let mut channel_lock = self.channel_state.lock().unwrap();
                        let channel_state = &mut *channel_lock;
                        match channel_state.by_id.entry(msg.channel_id) {
@@ -2501,7 +2519,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                        if chan.get().get_counterparty_node_id() != *counterparty_node_id {
                                                return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!".to_owned(), msg.channel_id));
                                        }
-                                       let monitor = match chan.get_mut().funding_signed(&msg, &self.logger) {
+                                       let monitor = match chan.get_mut().funding_signed(&msg, last_block_hash, &self.logger) {
                                                Ok(update) => update,
                                                Err(e) => try_chan_entry!(self, Err(e), channel_state, chan),
                                        };
@@ -3237,9 +3255,14 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                // Note that we MUST NOT end up calling methods on self.chain_monitor here - we're called
                // during initialization prior to the chain_monitor being fully configured in some cases.
                // See the docs for `ChannelManagerReadArgs` for more.
-               let header_hash = header.block_hash();
-               log_trace!(self.logger, "Block {} at height {} connected", header_hash, height);
+               let block_hash = header.block_hash();
+               log_trace!(self.logger, "Block {} at height {} connected", block_hash, height);
+
                let _persistence_guard = PersistenceNotifierGuard::new(&self.total_consistency_lock, &self.persistence_notifier);
+
+               self.latest_block_height.store(height as usize, Ordering::Release);
+               *self.last_block_hash.write().unwrap() = block_hash;
+
                let mut failed_channels = Vec::new();
                let mut timed_out_htlcs = Vec::new();
                {
@@ -3328,8 +3351,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                for (source, payment_hash, reason) in timed_out_htlcs.drain(..) {
                        self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), source, &payment_hash, reason);
                }
-               self.latest_block_height.store(height as usize, Ordering::Release);
-               *self.last_block_hash.try_lock().expect("block_(dis)connected must not be called in parallel") = header_hash;
+
                loop {
                        // Update last_node_announcement_serial to be the max of its current value and the
                        // block timestamp. This should keep us close to the current time without relying on
@@ -3353,6 +3375,10 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                // during initialization prior to the chain_monitor being fully configured in some cases.
                // See the docs for `ChannelManagerReadArgs` for more.
                let _persistence_guard = PersistenceNotifierGuard::new(&self.total_consistency_lock, &self.persistence_notifier);
+
+               self.latest_block_height.fetch_sub(1, Ordering::AcqRel);
+               *self.last_block_hash.write().unwrap() = header.prev_blockhash;
+
                let mut failed_channels = Vec::new();
                {
                        let mut channel_lock = self.channel_state.lock().unwrap();
@@ -3376,9 +3402,8 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                }
                        });
                }
+
                self.handle_init_event_channel_failures(failed_channels);
-               self.latest_block_height.fetch_sub(1, Ordering::AcqRel);
-               *self.last_block_hash.try_lock().expect("block_(dis)connected must not be called in parallel") = header.block_hash();
        }
 
        /// Blocks until ChannelManager needs to be persisted or a timeout is reached. It returns a bool
@@ -3934,7 +3959,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> Writeable f
 
                self.genesis_hash.write(writer)?;
                (self.latest_block_height.load(Ordering::Acquire) as u32).write(writer)?;
-               self.last_block_hash.lock().unwrap().write(writer)?;
+               self.last_block_hash.read().unwrap().write(writer)?;
 
                let channel_state = self.channel_state.lock().unwrap();
                let mut unfunded_channels = 0;
@@ -4005,8 +4030,8 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> Writeable f
 /// At a high-level, the process for deserializing a ChannelManager and resuming normal operation
 /// is:
 /// 1) Deserialize all stored ChannelMonitors.
-/// 2) Deserialize the ChannelManager by filling in this struct and calling <(Option<BlockHash>,
-///    ChannelManager)>::read(reader, args).
+/// 2) Deserialize the ChannelManager by filling in this struct and calling:
+///    <(BlockHash, ChannelManager)>::read(reader, args)
 ///    This may result in closing some Channels if the ChannelMonitor is newer than the stored
 ///    ChannelManager state to ensure no loss of funds. Thus, transactions may be broadcasted.
 /// 3) If you are not fetching full blocks, register all relevant ChannelMonitor outpoints the same
@@ -4097,7 +4122,7 @@ impl<'a, Signer: 'a + Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
 // Implement ReadableArgs for an Arc'd ChannelManager to make it a bit easier to work with the
 // SipmleArcChannelManager type:
 impl<'a, Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
-       ReadableArgs<ChannelManagerReadArgs<'a, Signer, M, T, K, F, L>> for (Option<BlockHash>, Arc<ChannelManager<Signer, M, T, K, F, L>>)
+       ReadableArgs<ChannelManagerReadArgs<'a, Signer, M, T, K, F, L>> for (BlockHash, Arc<ChannelManager<Signer, M, T, K, F, L>>)
        where M::Target: chain::Watch<Signer>,
         T::Target: BroadcasterInterface,
         K::Target: KeysInterface<Signer = Signer>,
@@ -4105,13 +4130,13 @@ impl<'a, Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
         L::Target: Logger,
 {
        fn read<R: ::std::io::Read>(reader: &mut R, args: ChannelManagerReadArgs<'a, Signer, M, T, K, F, L>) -> Result<Self, DecodeError> {
-               let (blockhash, chan_manager) = <(Option<BlockHash>, ChannelManager<Signer, M, T, K, F, L>)>::read(reader, args)?;
+               let (blockhash, chan_manager) = <(BlockHash, ChannelManager<Signer, M, T, K, F, L>)>::read(reader, args)?;
                Ok((blockhash, Arc::new(chan_manager)))
        }
 }
 
 impl<'a, Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
-       ReadableArgs<ChannelManagerReadArgs<'a, Signer, M, T, K, F, L>> for (Option<BlockHash>, ChannelManager<Signer, M, T, K, F, L>)
+       ReadableArgs<ChannelManagerReadArgs<'a, Signer, M, T, K, F, L>> for (BlockHash, ChannelManager<Signer, M, T, K, F, L>)
        where M::Target: chain::Watch<Signer>,
         T::Target: BroadcasterInterface,
         K::Target: KeysInterface<Signer = Signer>,
@@ -4137,10 +4162,6 @@ impl<'a, Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
                let mut short_to_id = HashMap::with_capacity(cmp::min(channel_count as usize, 128));
                for _ in 0..channel_count {
                        let mut channel: Channel<Signer> = Channel::read(reader, &args.keys_manager)?;
-                       if channel.last_block_connected != Default::default() && channel.last_block_connected != last_block_hash {
-                               return Err(DecodeError::InvalidValue);
-                       }
-
                        let funding_txo = channel.get_funding_txo().ok_or(DecodeError::InvalidValue)?;
                        funding_txo_set.insert(funding_txo.clone());
                        if let Some(ref mut monitor) = args.channel_monitors.get_mut(&funding_txo) {
@@ -4240,7 +4261,7 @@ impl<'a, Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
                        tx_broadcaster: args.tx_broadcaster,
 
                        latest_block_height: AtomicUsize::new(latest_block_height as usize),
-                       last_block_hash: Mutex::new(last_block_hash),
+                       last_block_hash: RwLock::new(last_block_hash),
                        secp_ctx,
 
                        channel_state: Mutex::new(ChannelHolder {
@@ -4273,12 +4294,7 @@ impl<'a, Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
                //TODO: Broadcast channel update for closed channels, but only after we've made a
                //connection or two.
 
-               let last_seen_block_hash = if last_block_hash == Default::default() {
-                       None
-               } else {
-                       Some(last_block_hash)
-               };
-               Ok((last_seen_block_hash, channel_manager))
+               Ok((last_block_hash.clone(), channel_manager))
        }
 }
 
index b0ffef2a57f7fec6d52d666c908cf5c9d03af083..e7204a045abd8a673bc49f0f782b8c06900c2b3f 100644 (file)
@@ -13,7 +13,7 @@
 use chain::Watch;
 use chain::channelmonitor::ChannelMonitor;
 use chain::transaction::OutPoint;
-use ln::channelmanager::{ChannelManager, ChannelManagerReadArgs, RAACommitmentOrder, PaymentPreimage, PaymentHash, PaymentSecret, PaymentSendFailure};
+use ln::channelmanager::{ChainParameters, ChannelManager, ChannelManagerReadArgs, RAACommitmentOrder, PaymentPreimage, PaymentHash, PaymentSecret, PaymentSendFailure};
 use routing::router::{Route, get_route};
 use routing::network_graph::{NetGraphMsgHandler, NetworkGraph};
 use ln::features::InitFeatures;
@@ -28,6 +28,7 @@ use util::config::UserConfig;
 use util::ser::{ReadableArgs, Writeable, Readable};
 
 use bitcoin::blockdata::block::{Block, BlockHeader};
+use bitcoin::blockdata::constants::genesis_block;
 use bitcoin::blockdata::transaction::{Transaction, TxOut};
 use bitcoin::network::constants::Network;
 
@@ -174,7 +175,7 @@ impl<'a, 'b, 'c> Drop for Node<'a, 'b, 'c> {
                                for (_, old_monitor) in old_monitors.iter() {
                                        let mut w = test_utils::TestVecWriter(Vec::new());
                                        old_monitor.write(&mut w).unwrap();
-                                       let (_, deserialized_monitor) = <(Option<BlockHash>, ChannelMonitor<EnforcingSigner>)>::read(
+                                       let (_, deserialized_monitor) = <(BlockHash, ChannelMonitor<EnforcingSigner>)>::read(
                                                &mut ::std::io::Cursor::new(&w.0), self.keys_manager).unwrap();
                                        deserialized_monitors.push(deserialized_monitor);
                                }
@@ -190,7 +191,7 @@ impl<'a, 'b, 'c> Drop for Node<'a, 'b, 'c> {
 
                                let mut w = test_utils::TestVecWriter(Vec::new());
                                self.node.write(&mut w).unwrap();
-                               <(Option<BlockHash>, ChannelManager<EnforcingSigner, &test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestLogger>)>::read(&mut ::std::io::Cursor::new(w.0), ChannelManagerReadArgs {
+                               <(BlockHash, ChannelManager<EnforcingSigner, &test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestLogger>)>::read(&mut ::std::io::Cursor::new(w.0), ChannelManagerReadArgs {
                                        default_config: UserConfig::default(),
                                        keys_manager: self.keys_manager,
                                        fee_estimator: &test_utils::TestFeeEstimator { sat_per_kw: 253 },
@@ -1163,7 +1164,13 @@ pub fn create_node_chanmgrs<'a, 'b>(node_count: usize, cfgs: &'a Vec<NodeCfg<'b>
                default_config.channel_options.announced_channel = true;
                default_config.peer_channel_config_limits.force_announced_channel_preference = false;
                default_config.own_channel_config.our_htlc_minimum_msat = 1000; // sanitization being done by the sender, to exerce receiver logic we need to lift of limit
-               let node = ChannelManager::new(Network::Testnet, cfgs[i].fee_estimator, &cfgs[i].chain_monitor, cfgs[i].tx_broadcaster, cfgs[i].logger, cfgs[i].keys_manager, if node_config[i].is_some() { node_config[i].clone().unwrap() } else { default_config }, 0);
+               let network = Network::Testnet;
+               let params = ChainParameters {
+                       network,
+                       latest_hash: genesis_block(network).header.block_hash(),
+                       latest_height: 0,
+               };
+               let node = ChannelManager::new(cfgs[i].fee_estimator, &cfgs[i].chain_monitor, cfgs[i].tx_broadcaster, cfgs[i].logger, cfgs[i].keys_manager, if node_config[i].is_some() { node_config[i].clone().unwrap() } else { default_config }, params);
                chanmgrs.push(node);
        }
 
index 6fbea2fee982e9c2d97dfc3390fc6375470bf808..4604d741ceff10c0ea456d358d21b811ebb8e6a3 100644 (file)
@@ -4292,7 +4292,7 @@ fn test_no_txn_manager_serialize_deserialize() {
        new_chain_monitor = test_utils::TestChainMonitor::new(Some(nodes[0].chain_source), nodes[0].tx_broadcaster.clone(), &logger, &fee_estimator, &persister, keys_manager);
        nodes[0].chain_monitor = &new_chain_monitor;
        let mut chan_0_monitor_read = &chan_0_monitor_serialized.0[..];
-       let (_, mut chan_0_monitor) = <(Option<BlockHash>, ChannelMonitor<EnforcingSigner>)>::read(
+       let (_, mut chan_0_monitor) = <(BlockHash, ChannelMonitor<EnforcingSigner>)>::read(
                &mut chan_0_monitor_read, keys_manager).unwrap();
        assert!(chan_0_monitor_read.is_empty());
 
@@ -4301,7 +4301,7 @@ fn test_no_txn_manager_serialize_deserialize() {
        let (_, nodes_0_deserialized_tmp) = {
                let mut channel_monitors = HashMap::new();
                channel_monitors.insert(chan_0_monitor.get_funding_txo().0, &mut chan_0_monitor);
-               <(Option<BlockHash>, ChannelManager<EnforcingSigner, &test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestLogger>)>::read(&mut nodes_0_read, ChannelManagerReadArgs {
+               <(BlockHash, ChannelManager<EnforcingSigner, &test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestLogger>)>::read(&mut nodes_0_read, ChannelManagerReadArgs {
                        default_config: config,
                        keys_manager,
                        fee_estimator: &fee_estimator,
@@ -4401,7 +4401,7 @@ fn test_manager_serialize_deserialize_events() {
        new_chain_monitor = test_utils::TestChainMonitor::new(Some(nodes[0].chain_source), nodes[0].tx_broadcaster.clone(), &logger, &fee_estimator, &persister, keys_manager);
        nodes[0].chain_monitor = &new_chain_monitor;
        let mut chan_0_monitor_read = &chan_0_monitor_serialized.0[..];
-       let (_, mut chan_0_monitor) = <(Option<BlockHash>, ChannelMonitor<EnforcingSigner>)>::read(
+       let (_, mut chan_0_monitor) = <(BlockHash, ChannelMonitor<EnforcingSigner>)>::read(
                &mut chan_0_monitor_read, keys_manager).unwrap();
        assert!(chan_0_monitor_read.is_empty());
 
@@ -4410,7 +4410,7 @@ fn test_manager_serialize_deserialize_events() {
        let (_, nodes_0_deserialized_tmp) = {
                let mut channel_monitors = HashMap::new();
                channel_monitors.insert(chan_0_monitor.get_funding_txo().0, &mut chan_0_monitor);
-               <(Option<BlockHash>, ChannelManager<EnforcingSigner, &test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestLogger>)>::read(&mut nodes_0_read, ChannelManagerReadArgs {
+               <(BlockHash, ChannelManager<EnforcingSigner, &test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestLogger>)>::read(&mut nodes_0_read, ChannelManagerReadArgs {
                        default_config: config,
                        keys_manager,
                        fee_estimator: &fee_estimator,
@@ -4493,7 +4493,7 @@ fn test_simple_manager_serialize_deserialize() {
        new_chain_monitor = test_utils::TestChainMonitor::new(Some(nodes[0].chain_source), nodes[0].tx_broadcaster.clone(), &logger, &fee_estimator, &persister, keys_manager);
        nodes[0].chain_monitor = &new_chain_monitor;
        let mut chan_0_monitor_read = &chan_0_monitor_serialized.0[..];
-       let (_, mut chan_0_monitor) = <(Option<BlockHash>, ChannelMonitor<EnforcingSigner>)>::read(
+       let (_, mut chan_0_monitor) = <(BlockHash, ChannelMonitor<EnforcingSigner>)>::read(
                &mut chan_0_monitor_read, keys_manager).unwrap();
        assert!(chan_0_monitor_read.is_empty());
 
@@ -4501,7 +4501,7 @@ fn test_simple_manager_serialize_deserialize() {
        let (_, nodes_0_deserialized_tmp) = {
                let mut channel_monitors = HashMap::new();
                channel_monitors.insert(chan_0_monitor.get_funding_txo().0, &mut chan_0_monitor);
-               <(Option<BlockHash>, ChannelManager<EnforcingSigner, &test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestLogger>)>::read(&mut nodes_0_read, ChannelManagerReadArgs {
+               <(BlockHash, ChannelManager<EnforcingSigner, &test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestLogger>)>::read(&mut nodes_0_read, ChannelManagerReadArgs {
                        default_config: UserConfig::default(),
                        keys_manager,
                        fee_estimator: &fee_estimator,
@@ -4577,7 +4577,7 @@ fn test_manager_serialize_deserialize_inconsistent_monitor() {
        let mut node_0_stale_monitors = Vec::new();
        for serialized in node_0_stale_monitors_serialized.iter() {
                let mut read = &serialized[..];
-               let (_, monitor) = <(Option<BlockHash>, ChannelMonitor<EnforcingSigner>)>::read(&mut read, keys_manager).unwrap();
+               let (_, monitor) = <(BlockHash, ChannelMonitor<EnforcingSigner>)>::read(&mut read, keys_manager).unwrap();
                assert!(read.is_empty());
                node_0_stale_monitors.push(monitor);
        }
@@ -4585,14 +4585,14 @@ fn test_manager_serialize_deserialize_inconsistent_monitor() {
        let mut node_0_monitors = Vec::new();
        for serialized in node_0_monitors_serialized.iter() {
                let mut read = &serialized[..];
-               let (_, monitor) = <(Option<BlockHash>, ChannelMonitor<EnforcingSigner>)>::read(&mut read, keys_manager).unwrap();
+               let (_, monitor) = <(BlockHash, ChannelMonitor<EnforcingSigner>)>::read(&mut read, keys_manager).unwrap();
                assert!(read.is_empty());
                node_0_monitors.push(monitor);
        }
 
        let mut nodes_0_read = &nodes_0_serialized[..];
        if let Err(msgs::DecodeError::InvalidValue) =
-               <(Option<BlockHash>, ChannelManager<EnforcingSigner, &test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestLogger>)>::read(&mut nodes_0_read, ChannelManagerReadArgs {
+               <(BlockHash, ChannelManager<EnforcingSigner, &test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestLogger>)>::read(&mut nodes_0_read, ChannelManagerReadArgs {
                default_config: UserConfig::default(),
                keys_manager,
                fee_estimator: &fee_estimator,
@@ -4606,7 +4606,7 @@ fn test_manager_serialize_deserialize_inconsistent_monitor() {
 
        let mut nodes_0_read = &nodes_0_serialized[..];
        let (_, nodes_0_deserialized_tmp) =
-               <(Option<BlockHash>, ChannelManager<EnforcingSigner, &test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestLogger>)>::read(&mut nodes_0_read, ChannelManagerReadArgs {
+               <(BlockHash, ChannelManager<EnforcingSigner, &test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestLogger>)>::read(&mut nodes_0_read, ChannelManagerReadArgs {
                default_config: UserConfig::default(),
                keys_manager,
                fee_estimator: &fee_estimator,
@@ -7462,7 +7462,7 @@ fn test_data_loss_protect() {
 
        // Restore node A from previous state
        logger = test_utils::TestLogger::with_id(format!("node {}", 0));
-       let mut chain_monitor = <(Option<BlockHash>, ChannelMonitor<EnforcingSigner>)>::read(&mut ::std::io::Cursor::new(previous_chain_monitor_state.0), keys_manager).unwrap().1;
+       let mut chain_monitor = <(BlockHash, ChannelMonitor<EnforcingSigner>)>::read(&mut ::std::io::Cursor::new(previous_chain_monitor_state.0), keys_manager).unwrap().1;
        chain_source = test_utils::TestChainSource::new(Network::Testnet);
        tx_broadcaster = test_utils::TestBroadcaster{txn_broadcasted: Mutex::new(Vec::new())};
        fee_estimator = test_utils::TestFeeEstimator { sat_per_kw: 253 };
@@ -7471,7 +7471,7 @@ fn test_data_loss_protect() {
        node_state_0 = {
                let mut channel_monitors = HashMap::new();
                channel_monitors.insert(OutPoint { txid: chan.3.txid(), index: 0 }, &mut chain_monitor);
-               <(Option<BlockHash>, ChannelManager<EnforcingSigner, &test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestLogger>)>::read(&mut ::std::io::Cursor::new(previous_node_state), ChannelManagerReadArgs {
+               <(BlockHash, ChannelManager<EnforcingSigner, &test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestLogger>)>::read(&mut ::std::io::Cursor::new(previous_node_state), ChannelManagerReadArgs {
                        keys_manager: keys_manager,
                        fee_estimator: &fee_estimator,
                        chain_monitor: &monitor,
@@ -8240,7 +8240,7 @@ fn test_update_err_monitor_lockdown() {
                let monitor = monitors.get(&outpoint).unwrap();
                let mut w = test_utils::TestVecWriter(Vec::new());
                monitor.write(&mut w).unwrap();
-               let new_monitor = <(Option<BlockHash>, channelmonitor::ChannelMonitor<EnforcingSigner>)>::read(
+               let new_monitor = <(BlockHash, channelmonitor::ChannelMonitor<EnforcingSigner>)>::read(
                                &mut ::std::io::Cursor::new(&w.0), &test_utils::OnlyReadsKeysInterface {}).unwrap().1;
                assert!(new_monitor == *monitor);
                let watchtower = test_utils::TestChainMonitor::new(Some(&chain_source), &chanmon_cfgs[0].tx_broadcaster, &logger, &chanmon_cfgs[0].fee_estimator, &persister, &node_cfgs[0].keys_manager);
@@ -8299,7 +8299,7 @@ fn test_concurrent_monitor_claim() {
                let monitor = monitors.get(&outpoint).unwrap();
                let mut w = test_utils::TestVecWriter(Vec::new());
                monitor.write(&mut w).unwrap();
-               let new_monitor = <(Option<BlockHash>, channelmonitor::ChannelMonitor<EnforcingSigner>)>::read(
+               let new_monitor = <(BlockHash, channelmonitor::ChannelMonitor<EnforcingSigner>)>::read(
                                &mut ::std::io::Cursor::new(&w.0), &test_utils::OnlyReadsKeysInterface {}).unwrap().1;
                assert!(new_monitor == *monitor);
                let watchtower = test_utils::TestChainMonitor::new(Some(&chain_source), &chanmon_cfgs[0].tx_broadcaster, &logger, &chanmon_cfgs[0].fee_estimator, &persister, &node_cfgs[0].keys_manager);
@@ -8325,7 +8325,7 @@ fn test_concurrent_monitor_claim() {
                let monitor = monitors.get(&outpoint).unwrap();
                let mut w = test_utils::TestVecWriter(Vec::new());
                monitor.write(&mut w).unwrap();
-               let new_monitor = <(Option<BlockHash>, channelmonitor::ChannelMonitor<EnforcingSigner>)>::read(
+               let new_monitor = <(BlockHash, channelmonitor::ChannelMonitor<EnforcingSigner>)>::read(
                                &mut ::std::io::Cursor::new(&w.0), &test_utils::OnlyReadsKeysInterface {}).unwrap().1;
                assert!(new_monitor == *monitor);
                let watchtower = test_utils::TestChainMonitor::new(Some(&chain_source), &chanmon_cfgs[0].tx_broadcaster, &logger, &chanmon_cfgs[0].fee_estimator, &persister, &node_cfgs[0].keys_manager);
index 165f86fc2665627e6bd5c909fdd5d7a6f4c1ce2d..b19a355d8f1acd6eca7115c79334f4788ee7fed6 100644 (file)
@@ -240,7 +240,7 @@ fn do_test_unconf_chan(reload_node: bool, reorg_after_reload: bool) {
                new_chain_monitor = test_utils::TestChainMonitor::new(Some(nodes[0].chain_source), nodes[0].tx_broadcaster.clone(), nodes[0].logger, node_cfgs[0].fee_estimator, &persister, keys_manager);
                nodes[0].chain_monitor = &new_chain_monitor;
                let mut chan_0_monitor_read = &chan_0_monitor_serialized.0[..];
-               let (_, mut chan_0_monitor) = <(Option<BlockHash>, ChannelMonitor<EnforcingSigner>)>::read(
+               let (_, mut chan_0_monitor) = <(BlockHash, ChannelMonitor<EnforcingSigner>)>::read(
                        &mut chan_0_monitor_read, keys_manager).unwrap();
                assert!(chan_0_monitor_read.is_empty());
 
@@ -249,7 +249,7 @@ fn do_test_unconf_chan(reload_node: bool, reorg_after_reload: bool) {
                nodes_0_deserialized = {
                        let mut channel_monitors = HashMap::new();
                        channel_monitors.insert(chan_0_monitor.get_funding_txo().0, &mut chan_0_monitor);
-                       <(Option<BlockHash>, ChannelManager<EnforcingSigner, &test_utils::TestChainMonitor, &test_utils::TestBroadcaster,
+                       <(BlockHash, ChannelManager<EnforcingSigner, &test_utils::TestChainMonitor, &test_utils::TestBroadcaster,
                          &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestLogger>)>::read(
                                &mut nodes_0_read, ChannelManagerReadArgs {
                                        default_config: config,
index b96169aadb8023244ba27188e2c955436da8f84b..ea110023823242c0e3ae5999e353db8c7c61f1b1 100644 (file)
@@ -109,7 +109,7 @@ impl<'a> chain::Watch<EnforcingSigner> for TestChainMonitor<'a> {
                // to a watchtower and disk...
                let mut w = TestVecWriter(Vec::new());
                monitor.write(&mut w).unwrap();
-               let new_monitor = <(Option<BlockHash>, channelmonitor::ChannelMonitor<EnforcingSigner>)>::read(
+               let new_monitor = <(BlockHash, channelmonitor::ChannelMonitor<EnforcingSigner>)>::read(
                        &mut ::std::io::Cursor::new(&w.0), self.keys_manager).unwrap().1;
                assert!(new_monitor == monitor);
                self.latest_monitor_update_id.lock().unwrap().insert(funding_txo.to_channel_id(), (funding_txo, monitor.get_latest_update_id()));
@@ -150,7 +150,7 @@ impl<'a> chain::Watch<EnforcingSigner> for TestChainMonitor<'a> {
                let monitor = monitors.get(&funding_txo).unwrap();
                w.0.clear();
                monitor.write(&mut w).unwrap();
-               let new_monitor = <(Option<BlockHash>, channelmonitor::ChannelMonitor<EnforcingSigner>)>::read(
+               let new_monitor = <(BlockHash, channelmonitor::ChannelMonitor<EnforcingSigner>)>::read(
                        &mut ::std::io::Cursor::new(&w.0), self.keys_manager).unwrap().1;
                assert!(new_monitor == *monitor);
                self.added_monitors.lock().unwrap().push((funding_txo, new_monitor));