Merge rust-bitcoin/rust-bitcoin#3660: Update `from_next_work_required` to take an i64 for timespan
4d0d78a3af
Fix typo in from_next_work_required documentation (Shing Him Ng)5e47c4123d
Update CompactTarget::from_next_work_required to take timespan as i64 (Shing Him Ng) Pull request description: [In Core](f7144b24be/src/pow.cpp (L56)
), the timespan is defined as a signed int64. This PR will update `from_next_work_required` to take in an `i64` instead of a `u64` Fixes #3652 ACKs for top commit: tcharding: ACK4d0d78a3af
apoelstra: ACK 4d0d78a3af2ca300c6b40348724e806bd51ef27a; successfully ran local tests Tree-SHA512: eea33ec18b081a97ae2a22c681982ad8693200ff8de3a3fc8f46b84b5e72f41589b79140ddd79ba3fce628f1539baf8387422bcc2c6b409fcadc4c2043aa2901
This commit is contained in:
commit
f95d877d56
|
@ -113,7 +113,7 @@ pub struct Params {
|
|||
/// Expected amount of time to mine one block.
|
||||
pub pow_target_spacing: u64,
|
||||
/// Difficulty recalculation interval.
|
||||
pub pow_target_timespan: u64,
|
||||
pub pow_target_timespan: u32,
|
||||
/// Determines whether minimal difficulty may be used for blocks or not.
|
||||
pub allow_min_difficulty_blocks: bool,
|
||||
/// Determines whether retargeting is disabled for this network or not.
|
||||
|
@ -261,7 +261,7 @@ impl Params {
|
|||
|
||||
/// Calculates the number of blocks between difficulty adjustments.
|
||||
pub fn difficulty_adjustment_interval(&self) -> u64 {
|
||||
self.pow_target_timespan / self.pow_target_spacing
|
||||
u64::from(self.pow_target_timespan) / self.pow_target_spacing
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -357,7 +357,7 @@ define_extension_trait! {
|
|||
/// ref: <https://github.com/bitcoin/bitcoin/blob/0503cbea9aab47ec0a87d34611e5453158727169/src/pow.cpp>
|
||||
///
|
||||
/// Given the previous Target, represented as a [`CompactTarget`], the difficulty is adjusted
|
||||
/// by taking the timespan between them, and multipling the current [`CompactTarget`] by a factor
|
||||
/// by taking the timespan between them, and multiplying the current [`CompactTarget`] by a factor
|
||||
/// of the net timespan and expected timespan. The [`CompactTarget`] may not adjust by more than
|
||||
/// a factor of 4, or adjust beyond the maximum threshold for the network.
|
||||
///
|
||||
|
@ -371,12 +371,14 @@ define_extension_trait! {
|
|||
/// Take the example of the first difficulty adjustment. Block 2016 introduces a new [`CompactTarget`],
|
||||
/// which takes the net timespan between Block 2015 and Block 0, and recomputes the difficulty.
|
||||
///
|
||||
/// To calculate the timespan, users should first convert their u32 timestamps to i64s before subtracting them
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// The expected [`CompactTarget`] recalculation.
|
||||
fn from_next_work_required(
|
||||
last: CompactTarget,
|
||||
timespan: u64,
|
||||
timespan: i64,
|
||||
params: impl AsRef<Params>,
|
||||
) -> CompactTarget {
|
||||
let params = params.as_ref();
|
||||
|
@ -387,11 +389,11 @@ define_extension_trait! {
|
|||
// ref: <https://github.com/bitcoin/bitcoin/blob/0503cbea9aab47ec0a87d34611e5453158727169/src/pow.cpp>
|
||||
let min_timespan = params.pow_target_timespan >> 2; // Lines 56/57
|
||||
let max_timespan = params.pow_target_timespan << 2; // Lines 58/59
|
||||
let actual_timespan = timespan.clamp(min_timespan, max_timespan);
|
||||
let actual_timespan = timespan.clamp(min_timespan.into(), max_timespan.into());
|
||||
let prev_target: Target = last.into();
|
||||
let maximum_retarget = prev_target.max_transition_threshold(params); // bnPowLimit
|
||||
let retarget = prev_target.0; // bnNew
|
||||
let retarget = retarget.mul(actual_timespan.into());
|
||||
let retarget = retarget.mul(u128::try_from(actual_timespan).expect("clamped value won't be negative").into());
|
||||
let retarget = retarget.div(params.pow_target_timespan.into());
|
||||
let retarget = Target(retarget);
|
||||
if retarget.ge(&maximum_retarget) {
|
||||
|
@ -1750,8 +1752,8 @@ mod tests {
|
|||
fn compact_target_from_upwards_difficulty_adjustment() {
|
||||
let params = Params::new(crate::Network::Signet);
|
||||
let starting_bits = CompactTarget::from_consensus(503543726); // Genesis compact target on Signet
|
||||
let start_time: u64 = 1598918400; // Genesis block unix time
|
||||
let end_time: u64 = 1599332177; // Block 2015 unix time
|
||||
let start_time: i64 = 1598918400; // Genesis block unix time
|
||||
let end_time: i64 = 1599332177; // Block 2015 unix time
|
||||
let timespan = end_time - start_time; // Faster than expected
|
||||
let adjustment = CompactTarget::from_next_work_required(starting_bits, timespan, ¶ms);
|
||||
let adjustment_bits = CompactTarget::from_consensus(503394215); // Block 2016 compact target
|
||||
|
@ -1762,8 +1764,8 @@ mod tests {
|
|||
fn compact_target_from_downwards_difficulty_adjustment() {
|
||||
let params = Params::new(crate::Network::Signet);
|
||||
let starting_bits = CompactTarget::from_consensus(503394215); // Block 2016 compact target
|
||||
let start_time: u64 = 1599332844; // Block 2016 unix time
|
||||
let end_time: u64 = 1600591200; // Block 4031 unix time
|
||||
let start_time: i64 = 1599332844; // Block 2016 unix time
|
||||
let end_time: i64 = 1600591200; // Block 4031 unix time
|
||||
let timespan = end_time - start_time; // Slower than expected
|
||||
let adjustment = CompactTarget::from_next_work_required(starting_bits, timespan, ¶ms);
|
||||
let adjustment_bits = CompactTarget::from_consensus(503397348); // Block 4032 compact target
|
||||
|
@ -1829,7 +1831,18 @@ mod tests {
|
|||
fn compact_target_from_maximum_upward_difficulty_adjustment() {
|
||||
let params = Params::new(crate::Network::Signet);
|
||||
let starting_bits = CompactTarget::from_consensus(503403001);
|
||||
let timespan = (0.2 * params.pow_target_timespan as f64) as u64;
|
||||
let timespan = params.pow_target_timespan / 5;
|
||||
let got = CompactTarget::from_next_work_required(starting_bits, timespan.into(), params);
|
||||
let want =
|
||||
Target::from_compact(starting_bits).min_transition_threshold().to_compact_lossy();
|
||||
assert_eq!(got, want);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn compact_target_from_maximum_upward_difficulty_adjustment_with_negative_timespan() {
|
||||
let params = Params::new(crate::Network::Signet);
|
||||
let starting_bits = CompactTarget::from_consensus(503403001);
|
||||
let timespan: i64 = -i64::from(params.pow_target_timespan);
|
||||
let got = CompactTarget::from_next_work_required(starting_bits, timespan, params);
|
||||
let want =
|
||||
Target::from_compact(starting_bits).min_transition_threshold().to_compact_lossy();
|
||||
|
@ -1841,7 +1854,7 @@ mod tests {
|
|||
let params = Params::new(crate::Network::Signet);
|
||||
let starting_bits = CompactTarget::from_consensus(403403001); // High difficulty for Signet
|
||||
let timespan = 5 * params.pow_target_timespan; // Really slow.
|
||||
let got = CompactTarget::from_next_work_required(starting_bits, timespan, ¶ms);
|
||||
let got = CompactTarget::from_next_work_required(starting_bits, timespan.into(), ¶ms);
|
||||
let want =
|
||||
Target::from_compact(starting_bits).max_transition_threshold(params).to_compact_lossy();
|
||||
assert_eq!(got, want);
|
||||
|
@ -1852,7 +1865,7 @@ mod tests {
|
|||
let params = Params::new(crate::Network::Signet);
|
||||
let starting_bits = CompactTarget::from_consensus(503543726); // Genesis compact target on Signet
|
||||
let timespan = 5 * params.pow_target_timespan; // Really slow.
|
||||
let got = CompactTarget::from_next_work_required(starting_bits, timespan, ¶ms);
|
||||
let got = CompactTarget::from_next_work_required(starting_bits, timespan.into(), ¶ms);
|
||||
let want = params.max_attainable_target.to_compact_lossy();
|
||||
assert_eq!(got, want);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue