X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning-block-sync%2Fsrc%2Fpoll.rs;h=e7171cf3656138036d50385691c96e419db29bcd;hb=bada71394e96971bcf29fe997ecc9602ec305da4;hp=1243d004aae7a2b56f8ac851624ab0c531f326eb;hpb=a9f8b6e052910999e07d99e7fd8ca911d119d2d4;p=rust-lightning diff --git a/lightning-block-sync/src/poll.rs b/lightning-block-sync/src/poll.rs index 1243d004..e7171cf3 100644 --- a/lightning-block-sync/src/poll.rs +++ b/lightning-block-sync/src/poll.rs @@ -1,8 +1,7 @@ //! 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; @@ -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, @@ -62,7 +61,7 @@ impl Validate for BlockHeaderData { fn validate(self, block_hash: BlockHash) -> BlockSourceResult { let pow_valid_block_hash = self.header .validate_pow(&self.header.target()) - .or_else(|e| Err(BlockSourceError::persistent(e)))?; + .map_err(BlockSourceError::persistent)?; if pow_valid_block_hash != block_hash { return Err(BlockSourceError::persistent("invalid block hash")); @@ -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 { - let pow_valid_block_hash = self.header - .validate_pow(&self.header.target()) - .or_else(|e| Err(BlockSourceError::persistent(e)))?; + let header = match &self { + BlockData::FullBlock(block) => &block.header, + BlockData::HeaderOnly(header) => header, + }; + + let pow_valid_block_hash = header + .validate_pow(&header.target()) + .map_err(BlockSourceError::persistent)?; 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 }) @@ -97,7 +103,7 @@ impl Validate for Block { } /// 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, @@ -130,8 +136,11 @@ impl ValidatedBlockHeader { if let Network::Bitcoin = network { if self.height % 2016 == 0 { - let previous_work = previous_header.header.work(); - if work > (previous_work << 2) || work < (previous_work >> 2) { + let target = self.header.target(); + let previous_target = previous_header.header.target(); + let min_target = previous_target >> 2; + let max_target = previous_target << 2; + if target > max_target || target < min_target { return Err(BlockSourceError::persistent("invalid difficulty transition")) } } else if self.header.bits != previous_header.header.bits { @@ -159,11 +168,11 @@ impl ValidatedBlockHeader { /// 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 @@ -175,7 +184,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`.