Move the CompactTarget type to primitives

Potentially the whole `pow` module will move to `primitives` but this
is not possible easily right now. However, we would like to be able to
move the `BlockHash` and `block::Header` types over to `primitives`
and doing so requires the `CompactTarget` to be there.

Move the `CompactTarget` type to `primitives` and re-export it from the
`primitives` crate root.

Note also, we re-export the type publicly from `bitcoin::pow`.
This commit is contained in:
Tobin C. Harding 2024-07-16 09:02:30 +10:00
parent a00bd7cc4d
commit 2ec901fd63
No known key found for this signature in database
GPG Key ID: 40BF9E4C269D6607
3 changed files with 50 additions and 37 deletions

View File

@ -18,6 +18,10 @@ use crate::consensus::encode::{self, Decodable, Encodable};
use crate::internal_macros::define_extension_trait; use crate::internal_macros::define_extension_trait;
use crate::network::Params; use crate::network::Params;
#[rustfmt::skip] // Keep public re-exports separate.
#[doc(inline)]
pub use primitives::CompactTarget;
/// Implement traits and methods shared by `Target` and `Work`. /// Implement traits and methods shared by `Target` and `Work`.
macro_rules! do_impl { macro_rules! do_impl {
($ty:ident) => { ($ty:ident) => {
@ -330,32 +334,6 @@ impl Target {
} }
do_impl!(Target); do_impl!(Target);
/// Encoding of 256-bit target as 32-bit float.
///
/// This is used to encode a target into the block header. Satoshi made this part of consensus code
/// in the original version of Bitcoin, likely copying an idea from OpenSSL.
///
/// OpenSSL's bignum (BN) type has an encoding, which is even called "compact" as in bitcoin, which
/// is exactly this format.
///
/// # Note on order/equality
///
/// Usage of the ordering and equality traits for this type may be surprising. Converting between
/// `CompactTarget` and `Target` is lossy *in both directions* (there are multiple `CompactTarget`
/// values that map to the same `Target` value). Ordering and equality for this type are defined in
/// terms of the underlying `u32`.
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct CompactTarget(u32);
impl CompactTarget {
/// Creates a [`CompactTarget`] from a consensus encoded `u32`.
pub fn from_consensus(bits: u32) -> Self { Self(bits) }
/// Returns the consensus encoded `u32` representation of this [`CompactTarget`].
pub fn to_consensus(self) -> u32 { self.0 }
}
define_extension_trait! { define_extension_trait! {
/// Extension functionality for the [`CompactTarget`] type. /// Extension functionality for the [`CompactTarget`] type.
pub trait CompactTargetExt impl for CompactTarget { pub trait CompactTargetExt impl for CompactTarget {
@ -467,16 +445,6 @@ impl Decodable for CompactTarget {
} }
} }
impl fmt::LowerHex for CompactTarget {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::LowerHex::fmt(&self.0, f) }
}
impl fmt::UpperHex for CompactTarget {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::UpperHex::fmt(&self.0, f) }
}
/// Big-endian 256 bit integer type. /// Big-endian 256 bit integer type.
// (high, low): u.0 contains the high bits, u.1 contains the low bits. // (high, low): u.0 contains the high bits, u.1 contains the low bits.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]

View File

@ -31,6 +31,7 @@ extern crate serde;
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
pub mod locktime; pub mod locktime;
pub mod opcodes; pub mod opcodes;
pub mod pow;
pub mod sequence; pub mod sequence;
#[doc(inline)] #[doc(inline)]
@ -40,7 +41,10 @@ pub use units::*;
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
pub use self::locktime::{absolute, relative}; pub use self::locktime::{absolute, relative};
#[doc(inline)] #[doc(inline)]
pub use self::sequence::Sequence; pub use self::{
pow::CompactTarget,
sequence::Sequence,
};
#[rustfmt::skip] #[rustfmt::skip]
#[allow(unused_imports)] #[allow(unused_imports)]

41
primitives/src/pow.rs Normal file
View File

@ -0,0 +1,41 @@
// SPDX-License-Identifier: CC0-1.0
//! Proof-of-work related integer types.
use core::fmt;
/// Encoding of 256-bit target as 32-bit float.
///
/// This is used to encode a target into the block header. Satoshi made this part of consensus code
/// in the original version of Bitcoin, likely copying an idea from OpenSSL.
///
/// OpenSSL's bignum (BN) type has an encoding, which is even called "compact" as in bitcoin, which
/// is exactly this format.
///
/// # Note on order/equality
///
/// Usage of the ordering and equality traits for this type may be surprising. Converting between
/// `CompactTarget` and `Target` is lossy *in both directions* (there are multiple `CompactTarget`
/// values that map to the same `Target` value). Ordering and equality for this type are defined in
/// terms of the underlying `u32`.
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct CompactTarget(u32);
impl CompactTarget {
/// Creates a [`CompactTarget`] from a consensus encoded `u32`.
pub fn from_consensus(bits: u32) -> Self { Self(bits) }
/// Returns the consensus encoded `u32` representation of this [`CompactTarget`].
pub fn to_consensus(self) -> u32 { self.0 }
}
impl fmt::LowerHex for CompactTarget {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::LowerHex::fmt(&self.0, f) }
}
impl fmt::UpperHex for CompactTarget {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::UpperHex::fmt(&self.0, f) }
}