Implement testnet minimum difficulty

This commit is contained in:
teor 2020-11-19 18:00:56 +10:00
parent bb9c4918bf
commit 750f096a99
2 changed files with 47 additions and 4 deletions

View File

@ -8,7 +8,7 @@ use crate::parameters::{Network, Network::*};
use std::collections::{BTreeMap, HashMap};
use std::ops::Bound::*;
use chrono::Duration;
use chrono::{DateTime, Duration, Utc};
/// A Zcash network upgrade.
///
@ -229,6 +229,37 @@ impl NetworkUpgrade {
}
}
/// Returns true if the gap between `block_time` and `previous_block_time` is
/// greater than the Testnet minimum difficulty time gap. This time gap
/// depends on the `network` and `block_height`.
///
/// Returns false on Mainnet, when `block_height` is less than the minimum
/// difficulty start height, and when the time gap is too small.
///
/// `block_time` can be less than, equal to, or greater than
/// `previous_block_time`, because block times are provided by miners.
///
/// Implements the Testnet minimum difficulty adjustment from ZIPs 205 and 208.
///
/// Spec Note: Some parts of ZIPs 205 and 208 previously specified an incorrect
/// check for the time gap. This function implements the correct "greater than"
/// check.
pub fn is_testnet_min_difficulty_block(
network: Network,
block_height: block::Height,
block_time: DateTime<Utc>,
previous_block_time: DateTime<Utc>,
) -> bool {
let block_time_gap = block_time - previous_block_time;
if let Some(min_difficulty_gap) =
NetworkUpgrade::minimum_difficulty_spacing_for_height(network, block_height)
{
block_time_gap > min_difficulty_gap
} else {
false
}
}
/// Returns the averaging window timespan for the network upgrade.
///
/// `AveragingWindowTimespan` from the Zcash specification.

View File

@ -32,7 +32,6 @@ pub const POW_MAX_ADJUST_UP_PERCENT: i32 = 16;
pub const POW_MAX_ADJUST_DOWN_PERCENT: i32 = 32;
/// Contains the context needed to calculate the adjusted difficulty for a block.
#[allow(dead_code)]
pub(super) struct AdjustedDifficulty {
/// The `header.time` field from the candidate block
candidate_time: DateTime<Utc>,
@ -149,8 +148,21 @@ impl AdjustedDifficulty {
/// Implements `ThresholdBits` from the Zcash specification, and the Testnet
/// minimum difficulty adjustment from ZIPs 205 and 208.
pub fn expected_difficulty_threshold(&self) -> CompactDifficulty {
// TODO: Testnet minimum difficulty
self.threshold_bits()
if NetworkUpgrade::is_testnet_min_difficulty_block(
self.network,
self.candidate_height,
self.candidate_time,
self.relevant_times[0],
) {
assert_eq!(
self.network,
Network::Testnet,
"invalid network: the minimum difficulty rule only applies on testnet"
);
ExpandedDifficulty::target_difficulty_limit(self.network).to_compact()
} else {
self.threshold_bits()
}
}
/// Calculate the `difficulty_threshold` for a candidate block, based on the