From 853026071f718f81e88157adf051ad3350bc6292 Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Sat, 4 May 2024 07:13:53 +1000 Subject: [PATCH] bitcoin: Use new BlockHeight and BlockInterval types We just added to now types that are thin wrappers around `u32`s for block heights and intervals. Add `Encodable` and `Decodable` impls and use the new types. While we are at it re-export the types from the crate root so users don't have to dig into the `units` crate. --- bitcoin/src/consensus/params.rs | 58 ++++++++++++++++--------------- bitcoin/src/lib.rs | 40 +++++++++++++++++++++ bitcoin/src/p2p/message.rs | 5 +-- bitcoin/src/p2p/message_filter.rs | 6 ++-- 4 files changed, 77 insertions(+), 32 deletions(-) diff --git a/bitcoin/src/consensus/params.rs b/bitcoin/src/consensus/params.rs index 306cb21d0..203e95de4 100644 --- a/bitcoin/src/consensus/params.rs +++ b/bitcoin/src/consensus/params.rs @@ -65,6 +65,8 @@ //! # } //! ``` +use units::{BlockHeight, BlockInterval}; + use crate::network::Network; #[cfg(doc)] use crate::pow::CompactTarget; @@ -79,17 +81,17 @@ pub struct Params { /// Time when BIP16 becomes active. pub bip16_time: u32, /// Block height at which BIP34 becomes active. - pub bip34_height: u32, + pub bip34_height: BlockHeight, /// Block height at which BIP65 becomes active. - pub bip65_height: u32, + pub bip65_height: BlockHeight, /// Block height at which BIP66 becomes active. - pub bip66_height: u32, + pub bip66_height: BlockHeight, /// Minimum blocks including miner confirmation of the total of 2016 blocks in a retargeting period, /// (nPowTargetTimespan / nPowTargetSpacing) which is also used for BIP9 deployments. /// Examples: 1916 for 95%, 1512 for testchains. - pub rule_change_activation_threshold: u32, + pub rule_change_activation_threshold: BlockInterval, /// Number of blocks with the same set of rules. - pub miner_confirmation_window: u32, + pub miner_confirmation_window: BlockInterval, /// Proof of work limit value. It contains the lowest possible difficulty. #[deprecated(since = "0.32.0", note = "field renamed to max_attainable_target")] pub pow_limit: Target, @@ -138,12 +140,12 @@ impl Params { /// The mainnet parameters. pub const MAINNET: Params = Params { network: Network::Bitcoin, - bip16_time: 1333238400, // Apr 1 2012 - bip34_height: 227931, // 000000000000024b89b42a942fe0d9fea3bb44ab7bd1b19115dd6a759c0808b8 - bip65_height: 388381, // 000000000000000004c2b624ed5d7756c508d90fd0da2c7c679febfa6c4735f0 - bip66_height: 363725, // 00000000000000000379eaa19dce8c9b722d46ae6a57c2f1a988119488b50931 - rule_change_activation_threshold: 1916, // 95% - miner_confirmation_window: 2016, + bip16_time: 1333238400, // Apr 1 2012 + bip34_height: BlockHeight::from_u32(227931), // 000000000000024b89b42a942fe0d9fea3bb44ab7bd1b19115dd6a759c0808b8 + bip65_height: BlockHeight::from_u32(388381), // 000000000000000004c2b624ed5d7756c508d90fd0da2c7c679febfa6c4735f0 + bip66_height: BlockHeight::from_u32(363725), // 00000000000000000379eaa19dce8c9b722d46ae6a57c2f1a988119488b50931 + rule_change_activation_threshold: BlockInterval::from_u32(1916), // 95% + miner_confirmation_window: BlockInterval::from_u32(2016), pow_limit: Target::MAX_ATTAINABLE_MAINNET, max_attainable_target: Target::MAX_ATTAINABLE_MAINNET, pow_target_spacing: 10 * 60, // 10 minutes. @@ -155,12 +157,12 @@ impl Params { /// The testnet parameters. pub const TESTNET: Params = Params { network: Network::Testnet, - bip16_time: 1333238400, // Apr 1 2012 - bip34_height: 21111, // 0000000023b3a96d3484e5abb3755c413e7d41500f8e2a5c3f0dd01299cd8ef8 - bip65_height: 581885, // 00000000007f6655f22f98e72ed80d8b06dc761d5da09df0fa1dc4be4f861eb6 - bip66_height: 330776, // 000000002104c8c45e99a8853285a3b592602a3ccde2b832481da85e9e4ba182 - rule_change_activation_threshold: 1512, // 75% - miner_confirmation_window: 2016, + bip16_time: 1333238400, // Apr 1 2012 + bip34_height: BlockHeight::from_u32(21111), // 0000000023b3a96d3484e5abb3755c413e7d41500f8e2a5c3f0dd01299cd8ef8 + bip65_height: BlockHeight::from_u32(581885), // 00000000007f6655f22f98e72ed80d8b06dc761d5da09df0fa1dc4be4f861eb6 + bip66_height: BlockHeight::from_u32(330776), // 000000002104c8c45e99a8853285a3b592602a3ccde2b832481da85e9e4ba182 + rule_change_activation_threshold: BlockInterval::from_u32(1512), // 75% + miner_confirmation_window: BlockInterval::from_u32(2016), pow_limit: Target::MAX_ATTAINABLE_TESTNET, max_attainable_target: Target::MAX_ATTAINABLE_TESTNET, pow_target_spacing: 10 * 60, // 10 minutes. @@ -173,11 +175,11 @@ impl Params { pub const SIGNET: Params = Params { network: Network::Signet, bip16_time: 1333238400, // Apr 1 2012 - bip34_height: 1, - bip65_height: 1, - bip66_height: 1, - rule_change_activation_threshold: 1916, // 95% - miner_confirmation_window: 2016, + bip34_height: BlockHeight::from_u32(1), + bip65_height: BlockHeight::from_u32(1), + bip66_height: BlockHeight::from_u32(1), + rule_change_activation_threshold: BlockInterval::from_u32(1916), // 95% + miner_confirmation_window: BlockInterval::from_u32(2016), pow_limit: Target::MAX_ATTAINABLE_SIGNET, max_attainable_target: Target::MAX_ATTAINABLE_SIGNET, pow_target_spacing: 10 * 60, // 10 minutes. @@ -189,12 +191,12 @@ impl Params { /// The regtest parameters. pub const REGTEST: Params = Params { network: Network::Regtest, - bip16_time: 1333238400, // Apr 1 2012 - bip34_height: 100000000, // not activated on regtest - bip65_height: 1351, - bip66_height: 1251, // used only in rpc tests - rule_change_activation_threshold: 108, // 75% - miner_confirmation_window: 144, + bip16_time: 1333238400, // Apr 1 2012 + bip34_height: BlockHeight::from_u32(100000000), // not activated on regtest + bip65_height: BlockHeight::from_u32(1351), + bip66_height: BlockHeight::from_u32(1251), // used only in rpc tests + rule_change_activation_threshold: BlockInterval::from_u32(108), // 75% + miner_confirmation_window: BlockInterval::from_u32(144), pow_limit: Target::MAX_ATTAINABLE_REGTEST, max_attainable_target: Target::MAX_ATTAINABLE_REGTEST, pow_target_spacing: 10 * 60, // 10 minutes. diff --git a/bitcoin/src/lib.rs b/bitcoin/src/lib.rs index 3db99fa7d..1d03fef81 100644 --- a/bitcoin/src/lib.rs +++ b/bitcoin/src/lib.rs @@ -139,6 +139,7 @@ pub use crate::{ sighash::{EcdsaSighashType, TapSighashType}, taproot::{TapBranchTag, TapLeafHash, TapLeafTag, TapNodeHash, TapTweakHash, TapTweakTag}, }; +pub use units::{BlockHeight, BlockInterval}; #[rustfmt::skip] #[allow(unused_imports)] @@ -200,3 +201,42 @@ pub mod parse { /// Re-export everything from the [`units::parse`] module. pub use units::parse::ParseIntError; } + +mod encode_impls { + //! Encodable/Decodable implementations. + // While we are deprecating, re-exporting, and generally moving things around just put these here. + + use units::{BlockHeight, BlockInterval}; + + use crate::consensus::{encode, Decodable, Encodable}; + use crate::io::{BufRead, Write}; + + /// Implements Encodable and Decodable for a simple wrapper type. + /// + /// Wrapper type is required to implement `to_u32()` and `From`. + macro_rules! impl_encodable_for_u32_wrapper { + ($ty:ident) => { + impl Decodable for $ty { + #[inline] + fn consensus_decode(r: &mut R) -> Result { + let inner = u32::consensus_decode(r)?; + Ok($ty::from(inner)) + } + } + + impl Encodable for $ty { + #[inline] + fn consensus_encode( + &self, + w: &mut W, + ) -> Result { + let inner = self.to_u32(); + inner.consensus_encode(w) + } + } + }; + } + + impl_encodable_for_u32_wrapper!(BlockHeight); + impl_encodable_for_u32_wrapper!(BlockInterval); +} diff --git a/bitcoin/src/p2p/message.rs b/bitcoin/src/p2p/message.rs index c96c023c0..0b2cf3cdc 100644 --- a/bitcoin/src/p2p/message.rs +++ b/bitcoin/src/p2p/message.rs @@ -537,6 +537,7 @@ mod test { use std::net::Ipv4Addr; use hex::test_hex_unwrap as hex; + use units::BlockHeight; use super::*; use crate::bip152::BlockTransactionsRequest; @@ -608,7 +609,7 @@ mod test { NetworkMessage::FilterClear, NetworkMessage::GetCFilters(GetCFilters { filter_type: 2, - start_height: 52, + start_height: BlockHeight::from(52), stop_hash: hash([42u8; 32]).into(), }), NetworkMessage::CFilter(CFilter { @@ -618,7 +619,7 @@ mod test { }), NetworkMessage::GetCFHeaders(GetCFHeaders { filter_type: 4, - start_height: 102, + start_height: BlockHeight::from(102), stop_hash: hash([47u8; 32]).into(), }), NetworkMessage::CFHeaders(CFHeaders { diff --git a/bitcoin/src/p2p/message_filter.rs b/bitcoin/src/p2p/message_filter.rs index 1537a73d2..fee412fac 100644 --- a/bitcoin/src/p2p/message_filter.rs +++ b/bitcoin/src/p2p/message_filter.rs @@ -4,6 +4,8 @@ //! //! This module describes BIP157 Client Side Block Filtering network messages. +use units::BlockHeight; + use crate::bip158::{FilterHash, FilterHeader}; use crate::blockdata::block::BlockHash; use crate::internal_macros::impl_consensus_encoding; @@ -14,7 +16,7 @@ pub struct GetCFilters { /// Filter type for which headers are requested pub filter_type: u8, /// The height of the first block in the requested range - pub start_height: u32, + pub start_height: BlockHeight, /// The hash of the last block in the requested range pub stop_hash: BlockHash, } @@ -38,7 +40,7 @@ pub struct GetCFHeaders { /// Byte identifying the type of filter being returned pub filter_type: u8, /// The height of the first block in the requested range - pub start_height: u32, + pub start_height: BlockHeight, /// The hash of the last block in the requested range pub stop_hash: BlockHash, }