Merge pull request #1777 from lexe-tech/max/best-block-header-best-block
authorJeffrey Czyz <jkczyz@gmail.com>
Wed, 19 Oct 2022 13:46:07 +0000 (08:46 -0500)
committerGitHub <noreply@github.com>
Wed, 19 Oct 2022 13:46:07 +0000 (08:46 -0500)
Add `.to_best_block()` method to `ValidatedBlockHeader`

1  2 
lightning-block-sync/src/poll.rs

index d45e900bad0b3733da3335cd9415001bd4c9a558,1243d004aae7a2b56f8ac851624ab0c531f326eb..05ccd4504fde0d81a76646d91b44d9b2b1653711
@@@ -1,9 -1,11 +1,10 @@@
  //! Adapters that make one or more [`BlockSource`]s simpler to poll for new chain tip transitions.
  
 -use crate::{AsyncBlockSourceResult, BlockHeaderData, BlockSource, BlockSourceError, BlockSourceResult};
 +use crate::{AsyncBlockSourceResult, BlockData, BlockHeaderData, BlockSource, BlockSourceError, BlockSourceResult};
  
 -use bitcoin::blockdata::block::Block;
  use bitcoin::hash_types::BlockHash;
  use bitcoin::network::constants::Network;
+ use lightning::chain::BestBlock;
  
  use std::ops::Deref;
  
@@@ -29,7 -31,7 +30,7 @@@ pub trait Poll 
  }
  
  /// A chain tip relative to another chain tip in terms of block hash and chainwork.
 -#[derive(Clone, Debug, PartialEq)]
 +#[derive(Clone, Debug, PartialEq, Eq)]
  pub enum ChainTip {
        /// A chain tip with the same hash as another chain's tip.
        Common,
@@@ -70,31 -72,24 +71,31 @@@ impl Validate for BlockHeaderData 
        }
  }
  
 -impl Validate for Block {
 +impl Validate for BlockData {
        type T = ValidatedBlock;
  
        fn validate(self, block_hash: BlockHash) -> BlockSourceResult<Self::T> {
 -              let pow_valid_block_hash = self.header
 -                      .validate_pow(&self.header.target())
 +              let header = match &self {
 +                      BlockData::FullBlock(block) => &block.header,
 +                      BlockData::HeaderOnly(header) => header,
 +              };
 +
 +              let pow_valid_block_hash = header
 +                      .validate_pow(&header.target())
                        .or_else(|e| Err(BlockSourceError::persistent(e)))?;
  
                if pow_valid_block_hash != block_hash {
                        return Err(BlockSourceError::persistent("invalid block hash"));
                }
  
 -              if !self.check_merkle_root() {
 -                      return Err(BlockSourceError::persistent("invalid merkle root"));
 -              }
 +              if let BlockData::FullBlock(block) = &self {
 +                      if !block.check_merkle_root() {
 +                              return Err(BlockSourceError::persistent("invalid merkle root"));
 +                      }
  
 -              if !self.check_witness_commitment() {
 -                      return Err(BlockSourceError::persistent("invalid witness commitment"));
 +                      if !block.check_witness_commitment() {
 +                              return Err(BlockSourceError::persistent("invalid witness commitment"));
 +                      }
                }
  
                Ok(ValidatedBlock { block_hash, inner: self })
  }
  
  /// A block header with validated proof of work and corresponding block hash.
 -#[derive(Clone, Copy, Debug, PartialEq)]
 +#[derive(Clone, Copy, Debug, PartialEq, Eq)]
  pub struct ValidatedBlockHeader {
        pub(crate) block_hash: BlockHash,
        inner: BlockHeaderData,
@@@ -146,16 -141,29 +147,29 @@@ impl ValidatedBlockHeader 
  
                Ok(())
        }
+     /// Returns the [`BestBlock`] corresponding to this validated block header, which can be passed
+     /// into [`ChannelManager::new`] as part of its [`ChainParameters`]. Useful for ensuring that
+     /// the [`SpvClient`] and [`ChannelManager`] are initialized to the same block during a fresh
+     /// start.
+     ///
+     /// [`SpvClient`]: crate::SpvClient
+     /// [`ChainParameters`]: lightning::ln::channelmanager::ChainParameters
+     /// [`ChannelManager`]: lightning::ln::channelmanager::ChannelManager
+     /// [`ChannelManager::new`]: lightning::ln::channelmanager::ChannelManager::new
+     pub fn to_best_block(&self) -> BestBlock {
+         BestBlock::new(self.block_hash, self.inner.height)
+     }
  }
  
  /// A block with validated data against its transaction list and corresponding block hash.
  pub struct ValidatedBlock {
        pub(crate) block_hash: BlockHash,
 -      inner: Block,
 +      inner: BlockData,
  }
  
  impl std::ops::Deref for ValidatedBlock {
 -      type Target = Block;
 +      type Target = BlockData;
  
        fn deref(&self) -> &Self::Target {
                &self.inner
@@@ -167,7 -175,7 +181,7 @@@ mod sealed 
        pub trait Validate {}
  
        impl Validate for crate::BlockHeaderData {}
 -      impl Validate for bitcoin::blockdata::block::Block {}
 +      impl Validate for crate::BlockData {}
  }
  
  /// The canonical `Poll` implementation used for a single `BlockSource`.