From 2ec901fd639f37aa4c25e1e630ad1a7051d7cc8f Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Tue, 16 Jul 2024 09:02:30 +1000 Subject: [PATCH] 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`. --- bitcoin/src/pow.rs | 40 ++++------------------------------------ primitives/src/lib.rs | 6 +++++- primitives/src/pow.rs | 41 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 37 deletions(-) create mode 100644 primitives/src/pow.rs diff --git a/bitcoin/src/pow.rs b/bitcoin/src/pow.rs index aa986a24b..7353e6db1 100644 --- a/bitcoin/src/pow.rs +++ b/bitcoin/src/pow.rs @@ -18,6 +18,10 @@ use crate::consensus::encode::{self, Decodable, Encodable}; use crate::internal_macros::define_extension_trait; 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`. macro_rules! do_impl { ($ty:ident) => { @@ -330,32 +334,6 @@ 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! { /// Extension functionality for the [`CompactTarget`] type. 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. // (high, low): u.0 contains the high bits, u.1 contains the low bits. #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] diff --git a/primitives/src/lib.rs b/primitives/src/lib.rs index 65074412e..78838eaf5 100644 --- a/primitives/src/lib.rs +++ b/primitives/src/lib.rs @@ -31,6 +31,7 @@ extern crate serde; #[cfg(feature = "alloc")] pub mod locktime; pub mod opcodes; +pub mod pow; pub mod sequence; #[doc(inline)] @@ -40,7 +41,10 @@ pub use units::*; #[cfg(feature = "alloc")] pub use self::locktime::{absolute, relative}; #[doc(inline)] -pub use self::sequence::Sequence; +pub use self::{ + pow::CompactTarget, + sequence::Sequence, +}; #[rustfmt::skip] #[allow(unused_imports)] diff --git a/primitives/src/pow.rs b/primitives/src/pow.rs new file mode 100644 index 000000000..b1e8aaa7f --- /dev/null +++ b/primitives/src/pow.rs @@ -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) } +}