From 73e8b542c096443f2b3d89a38164d851519e99c3 Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Fri, 18 Jul 2014 16:41:09 -0700 Subject: [PATCH] Add testnet blockspacing rule --- src/blockdata/blockchain.rs | 25 +++++++++++++++++++++---- src/blockdata/constants.rs | 1 + 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/blockdata/blockchain.rs b/src/blockdata/blockchain.rs index 9848b3bc..4e27ce87 100644 --- a/src/blockdata/blockchain.rs +++ b/src/blockdata/blockchain.rs @@ -30,8 +30,9 @@ use std::kinds::marker; use blockdata::block::{Block, BlockHeader}; use blockdata::transaction::Transaction; -use blockdata::constants::{DIFFCHANGE_INTERVAL, DIFFCHANGE_TIMESPAN, max_target, genesis_block}; -use network::constants::Network; +use blockdata::constants::{DIFFCHANGE_INTERVAL, DIFFCHANGE_TIMESPAN, + TARGET_BLOCK_SPACING, max_target, genesis_block}; +use network::constants::{Network, BitcoinTestnet}; use network::serialize::{Serializable, SerializeIter}; use util::BitArray; use util::error::{BitcoinResult, BlockNotFound, DuplicateHash, PrevHashNotFound}; @@ -491,9 +492,25 @@ impl Blockchain { if target > max { target = max }; // Compactify (make expressible in the 8+24 nBits float format satoshi_the_precision(&target) - } else { + // On non-diffchange blocks, Testnet has a rule that any 20-minute-long + // block intervals result the difficulty + } else if self.network == BitcoinTestnet && + block.header.time > prev.block.header.time + 2*TARGET_BLOCK_SPACING { + max_target(self.network) + // On the other hand, if we are in Testnet and the block interval is less + // than 20 minutes, we need to scan backward to find a block for which the + // previous rule did not apply, to find the "real" difficulty. + } else if self.network == BitcoinTestnet { + // Scan back DIFFCHANGE_INTERVAL blocks + let mut scan = prev.clone(); + while scan.height % DIFFCHANGE_INTERVAL != 0 && + scan.required_difficulty == max_target(self.network) { + scan = scan.prev(&self.tree).unwrap(); + } + scan.required_difficulty // Otherwise just use the last block's difficulty - prev.required_difficulty + } else { + prev.required_difficulty }; // Create node let ret = Rc::new(BlockchainNode { diff --git a/src/blockdata/constants.rs b/src/blockdata/constants.rs index 39377519..a47d41cc 100644 --- a/src/blockdata/constants.rs +++ b/src/blockdata/constants.rs @@ -33,6 +33,7 @@ use util::uint::Uint256; pub static MAX_SEQUENCE: u32 = 0xFFFFFFFF; pub static COIN_VALUE: u64 = 100000000; +pub static TARGET_BLOCK_SPACING: u32 = 600; pub static DIFFCHANGE_INTERVAL: u32 = 2016; pub static DIFFCHANGE_TIMESPAN: u32 = 14 * 24 * 3600;