Skip to content

Commit

Permalink
Improve API for max target threshold calculation
Browse files Browse the repository at this point in the history
The maximum target threshold has a network dependant upper bound.
Currently we are not checking this bound. One complication is that there
is currently heated open debate around the `Network` type.

We can bypass the `Network` issue by using `AsRef<Params>` instead.

Add a function that does the checks based on the `Params` type as well
as an unchecked version.
  • Loading branch information
tcharding committed Apr 2, 2024
1 parent 6e47d57 commit fd6fedc
Showing 1 changed file with 28 additions and 2 deletions.
30 changes: 28 additions & 2 deletions bitcoin/src/pow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
//! functions here are designed to be fast, by that we mean it is safe to use them to check headers.
//!

use core::cmp;
use core::fmt::{self, LowerHex, UpperHex};
use core::ops::{Add, Div, Mul, Not, Rem, Shl, Shr, Sub};

Expand Down Expand Up @@ -261,22 +262,47 @@ impl Target {
/// Computes the maximum valid [`Target`] threshold allowed for a block in which a difficulty
/// adjustment occurs.
#[deprecated(since = "TBD", note = "use max_transition_threshold instead")]
pub fn max_difficulty_transition_threshold(&self) -> Self { self.max_transition_threshold() }
pub fn max_difficulty_transition_threshold(&self) -> Self {
self.max_transition_threshold_unchecked()
}

/// Computes the minimum valid [`Target`] threshold allowed for a block in which a difficulty
/// adjustment occurs.
///
/// The difficulty can only decrease or increase by a factor of 4 max on each difficulty
/// adjustment period.
///
/// # Returns
///
/// In line with Bitcoin Core this function may return a target value of zero.
pub fn min_transition_threshold(&self) -> Self { Self(self.0 >> 2) }

/// Computes the maximum valid [`Target`] threshold allowed for a block in which a difficulty
/// adjustment occurs.
///
/// The difficulty can only decrease or increase by a factor of 4 max on each difficulty
/// adjustment period.
pub fn max_transition_threshold(&self) -> Self { Self(self.0 << 2) }
///
/// We also check that the calculated target is not greater than the maximum allowed target,
/// this value is network specific - hence the `params` parameter.
pub fn max_transition_threshold(&self, params: impl AsRef<Params>) -> Self {
let max_attainable = params.as_ref().max_attainable_target;
cmp::min(self.max_transition_threshold_unchecked(), max_attainable)
}

/// Computes the maximum valid [`Target`] threshold allowed for a block in which a difficulty
/// adjustment occurs.
///
/// The difficulty can only decrease or increase by a factor of 4 max on each difficulty
/// adjustment period.
///
/// # Returns
///
/// This function may return a value greater than the maximum allowed target for this network.
///
/// The return value should be checked against [`Params::max_attainable_target`] or use one of
/// the `Target::MAX_ATTAINABLE_FOO` constants.
pub fn max_transition_threshold_unchecked(&self) -> Self { Self(self.0 << 2) }
}
do_impl!(Target);

Expand Down

0 comments on commit fd6fedc

Please sign in to comment.