Improve API for max target threshold calculation

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.
This commit is contained in:
Tobin C. Harding 2024-01-30 08:20:33 +11:00
parent 6e47d57744
commit fd6fedc3ad
No known key found for this signature in database
GPG Key ID: 40BF9E4C269D6607
1 changed files with 28 additions and 2 deletions

View File

@ -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};
@ -261,13 +262,19 @@ 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
@ -275,8 +282,27 @@ impl Target {
///
/// 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);