Merge pull request #819 from TheBlueMatt/2021-03-810-rebased
authorMatt Corallo <649246+TheBlueMatt@users.noreply.github.com>
Wed, 3 Mar 2021 00:04:23 +0000 (16:04 -0800)
committerGitHub <noreply@github.com>
Wed, 3 Mar 2021 00:04:23 +0000 (16:04 -0800)
Change ChannelManager deserialization to return an optional blockhash

1  2 
lightning-block-sync/src/init.rs
lightning/src/ln/channelmanager.rs

index 83e356919b8e231a8d4a3bda41b0d65645e146fc,3e421fc44a9542b7e0a9fb5aa963d2c4bcca4c0d..59c057157ef14bd6332d0bad1c2207b2919e741c
@@@ -7,18 -7,6 +7,18 @@@ use bitcoin::network::constants::Networ
  
  use lightning::chain;
  
 +/// Returns a validated block header of the source's best chain tip.
 +///
 +/// Upon success, the returned header can be used to initialize [`SpvClient`]. Useful during a fresh
 +/// start when there are no chain listeners to sync yet.
 +pub async fn validate_best_block_header<B: BlockSource>(block_source: &mut B) ->
 +BlockSourceResult<ValidatedBlockHeader> {
 +      let (best_block_hash, best_block_height) = block_source.get_best_block().await?;
 +      block_source
 +              .get_header(&best_block_hash, best_block_height).await?
 +              .validate(best_block_hash)
 +}
 +
  /// Performs a one-time sync of chain listeners using a single *trusted* block source, bringing each
  /// listener's view of the chain from its paired block hash to `block_source`'s best chain tip.
  ///
  /// ) {
  ///   // Read a serialized channel monitor paired with the block hash when it was persisted.
  ///   let serialized_monitor = "...";
- ///   let (monitor_block_hash, mut monitor) = <(BlockHash, ChannelMonitor<S>)>::read(
+ ///   let (monitor_block_hash_option, mut monitor) = <(Option<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, mut manager) = {
+ ///   let (manager_block_hash_option, mut manager) = {
  ///           let read_args = ChannelManagerReadArgs::new(
  ///                   keys_manager,
  ///                   fee_estimator,
  ///                   config,
  ///                   vec![&mut monitor],
  ///           );
- ///           <(BlockHash, ChannelManager<S, &ChainMonitor<S, &C, &T, &F, &L, &P>, &T, &K, &F, &L>)>::read(
+ ///           <(Option<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 listeners = vec![
- ///           (monitor_block_hash, &mut monitor_listener as &mut dyn chain::Listen),
- ///           (manager_block_hash, &mut manager as &mut dyn chain::Listen),
- ///   ];
+ ///   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 chain_tip = init::synchronize_listeners(
  ///           block_source, Network::Bitcoin, &mut cache, listeners).await.unwrap();
  ///
@@@ -122,7 -113,10 +125,7 @@@ pub async fn synchronize_listeners<B: B
        header_cache: &mut C,
        mut chain_listeners: Vec<(BlockHash, &mut dyn chain::Listen)>,
  ) -> BlockSourceResult<ValidatedBlockHeader> {
 -      let (best_block_hash, best_block_height) = block_source.get_best_block().await?;
 -      let best_header = block_source
 -              .get_header(&best_block_hash, best_block_height).await?
 -              .validate(best_block_hash)?;
 +      let best_header = validate_best_block_header(block_source).await?;
  
        // Fetch the header for the block hash paired with each listener.
        let mut chain_listeners_with_old_headers = Vec::new();
index 0eca37f2c9faa3e2f38a26b77ec299df1478b0bb,d3e520f7409a0aee5f8a5b40e4e8d469039fcda1..b56ce5d9d052aa38c955d172e498d6cde4260713
@@@ -349,7 -349,7 +349,7 @@@ const ERR: () = "You need at least 32 b
  /// issues such as overly long function definitions. Note that the ChannelManager can take any
  /// type that implements KeysInterface for its keys manager, but this type alias chooses the
  /// concrete type of the KeysManager.
 -pub type SimpleArcChannelManager<M, T, F, L> = Arc<ChannelManager<InMemorySigner, Arc<M>, Arc<T>, Arc<KeysManager>, Arc<F>, Arc<L>>>;
 +pub type SimpleArcChannelManager<M, T, F, L> = ChannelManager<InMemorySigner, Arc<M>, Arc<T>, Arc<KeysManager>, Arc<F>, Arc<L>>;
  
  /// SimpleRefChannelManager is a type alias for a ChannelManager reference, and is the reference
  /// counterpart to the SimpleArcChannelManager type alias. Use this type by default when you don't
@@@ -380,7 -380,7 +380,7 @@@ pub type SimpleRefChannelManager<'a, 'b
  /// 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 (Sha256dHash, ChannelManager), which
+ /// Note that the deserializer is only implemented for (Option<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
@@@ -3925,7 -3925,7 +3925,7 @@@ impl<Signer: Sign, M: Deref, T: Deref, 
  /// 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 <(Sha256dHash,
+ /// 2) Deserialize the ChannelManager by filling in this struct and calling <(Option<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.
@@@ -4006,7 -4006,7 +4006,7 @@@ impl<'a, Signer: 'a + Sign, M: Deref, T
  // 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 (BlockHash, Arc<ChannelManager<Signer, M, T, K, F, L>>)
+       ReadableArgs<ChannelManagerReadArgs<'a, Signer, M, T, K, F, L>> for (Option<BlockHash>, Arc<ChannelManager<Signer, M, T, K, F, L>>)
        where M::Target: chain::Watch<Signer>,
          T::Target: BroadcasterInterface,
          K::Target: KeysInterface<Signer = Signer>,
          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) = <(BlockHash, ChannelManager<Signer, M, T, K, F, L>)>::read(reader, args)?;
+               let (blockhash, chan_manager) = <(Option<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 (BlockHash, ChannelManager<Signer, M, T, K, F, L>)
+       ReadableArgs<ChannelManagerReadArgs<'a, Signer, M, T, K, F, L>> for (Option<BlockHash>, ChannelManager<Signer, M, T, K, F, L>)
        where M::Target: chain::Watch<Signer>,
          T::Target: BroadcasterInterface,
          K::Target: KeysInterface<Signer = Signer>,
                //TODO: Broadcast channel update for closed channels, but only after we've made a
                //connection or two.
  
-               Ok((last_block_hash.clone(), channel_manager))
+               let last_seen_block_hash = if last_block_hash == Default::default() {
+                       None
+               } else {
+                       Some(last_block_hash)
+               };
+               Ok((last_seen_block_hash, channel_manager))
        }
  }