Merge pull request #477 from paritytech/hardcode_bch_daa_height

Bitcoin Cash: hardcode DAA HF height
This commit is contained in:
Marek Kotewicz 2018-01-09 12:40:40 +01:00 committed by GitHub
commit 9006e7acb3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 41 additions and 31 deletions

View File

@ -48,7 +48,7 @@ impl LogFormatter for DateAndColorLogFormatter {
pub fn init<T>(filters: &str, formatter: T) where T: LogFormatter {
let mut builder = LogBuilder::new();
let filters = match env::var("RUST_LOG") {
Ok(env_filters) => format!("{},{}", env_filters, filters),
Ok(env_filters) => format!("{},{}", filters, env_filters),
Err(_) => filters.into(),
};

View File

@ -1,9 +1,6 @@
use hash::H256;
use {Network, Magic, Deployment};
/// First block of BitcoinCash fork.
const BITCOIN_CASH_FORK_BLOCK: u32 = 478559; // https://blockchair.com/bitcoin-cash/block/478559
#[derive(Debug, Clone)]
/// Parameters that influence chain consensus.
pub struct ConsensusParams {
@ -38,10 +35,9 @@ pub struct ConsensusParams {
pub struct BitcoinCashConsensusParams {
/// Initial BCH hard fork height.
pub height: u32,
/// Time when difficulty adjustment hardfork becomes active (~Nov 13 2017).
/// Time when difficulty adjustment hardfork becomes active.
/// https://reviews.bitcoinabc.org/D601
// TODO: change to height after activation
pub difficulty_adjustion_time: u32,
pub difficulty_adjustion_height: u32,
}
#[derive(Debug, Clone)]
@ -227,11 +223,21 @@ impl ConsensusFork {
}
}
impl Default for BitcoinCashConsensusParams {
fn default() -> Self {
BitcoinCashConsensusParams {
height: BITCOIN_CASH_FORK_BLOCK,
difficulty_adjustion_time: 1510600000,
impl BitcoinCashConsensusParams {
pub fn new(network: Network) -> Self {
match network {
Network::Mainnet | Network::Other(_) => BitcoinCashConsensusParams {
height: 478559,
difficulty_adjustion_height: 504031,
},
Network::Testnet => BitcoinCashConsensusParams {
height: 1155876,
difficulty_adjustion_height: 1188697,
},
Network::Regtest | Network::Unitest => BitcoinCashConsensusParams {
height: 0,
difficulty_adjustion_height: 0,
},
}
}
}
@ -239,7 +245,7 @@ impl Default for BitcoinCashConsensusParams {
#[cfg(test)]
mod tests {
use super::super::Network;
use super::{ConsensusParams, ConsensusFork};
use super::{ConsensusParams, ConsensusFork, BitcoinCashConsensusParams};
#[test]
fn test_consensus_params_bip34_height() {
@ -279,7 +285,7 @@ mod tests {
#[test]
fn test_consensus_fork_min_block_size() {
assert_eq!(ConsensusFork::NoFork.min_block_size(0), 0);
let fork = ConsensusFork::BitcoinCash(Default::default());
let fork = ConsensusFork::BitcoinCash(BitcoinCashConsensusParams::new(Network::Mainnet));
assert_eq!(fork.min_block_size(0), 0);
assert_eq!(fork.min_block_size(fork.activation_height()), 1_000_001);
}
@ -287,13 +293,13 @@ mod tests {
#[test]
fn test_consensus_fork_max_transaction_size() {
assert_eq!(ConsensusFork::NoFork.max_transaction_size(), 1_000_000);
assert_eq!(ConsensusFork::BitcoinCash(Default::default()).max_transaction_size(), 1_000_000);
assert_eq!(ConsensusFork::BitcoinCash(BitcoinCashConsensusParams::new(Network::Mainnet)).max_transaction_size(), 1_000_000);
}
#[test]
fn test_consensus_fork_max_block_sigops() {
assert_eq!(ConsensusFork::NoFork.max_block_sigops(0, 1_000_000), 20_000);
let fork = ConsensusFork::BitcoinCash(Default::default());
let fork = ConsensusFork::BitcoinCash(BitcoinCashConsensusParams::new(Network::Mainnet));
assert_eq!(fork.max_block_sigops(0, 1_000_000), 20_000);
assert_eq!(fork.max_block_sigops(fork.activation_height(), 2_000_000), 40_000);
assert_eq!(fork.max_block_sigops(fork.activation_height() + 100, 3_000_000), 60_000);

View File

@ -211,7 +211,7 @@ mod tests {
use tokio_io::{AsyncRead, AsyncWrite};
use bytes::Bytes;
use ser::Stream;
use network::{Network, ConsensusFork};
use network::{Network, ConsensusFork, BitcoinCashConsensusParams};
use message::{Message, Error};
use message::types::Verack;
use message::types::version::{Version, V0, V106, V70001};
@ -389,7 +389,7 @@ mod tests {
#[test]
fn test_fails_to_accept_other_fork_node() {
let magic1 = Network::Mainnet.magic(&ConsensusFork::NoFork);
let magic2 = Network::Mainnet.magic(&ConsensusFork::BitcoinCash(Default::default()));
let magic2 = Network::Mainnet.magic(&ConsensusFork::BitcoinCash(BitcoinCashConsensusParams::new(Network::Mainnet)));
let version = 70012;
let local_version = local_version();
let remote_version = remote_version();

View File

@ -2,7 +2,7 @@ use std::net;
use clap;
use db;
use message::Services;
use network::{Network, ConsensusParams, ConsensusFork};
use network::{Network, ConsensusParams, ConsensusFork, BitcoinCashConsensusParams};
use p2p::InternetProtocol;
use seednodes::{mainnet_seednodes, testnet_seednodes, bitcoin_cash_seednodes, bitcoin_cash_testnet_seednodes};
use rpc_apis::ApiSet;
@ -57,7 +57,7 @@ pub fn parse(matches: &clap::ArgMatches) -> Result<Config, String> {
(true, true) => return Err("Only one testnet option can be used".into()),
};
let consensus_fork = parse_consensus_fork(&db, &matches)?;
let consensus_fork = parse_consensus_fork(network, &db, &matches)?;
let consensus = ConsensusParams::new(network, consensus_fork);
let (in_connections, out_connections) = match network {
@ -167,7 +167,7 @@ pub fn parse(matches: &clap::ArgMatches) -> Result<Config, String> {
Ok(config)
}
fn parse_consensus_fork(db: &db::SharedStore, matches: &clap::ArgMatches) -> Result<ConsensusFork, String> {
fn parse_consensus_fork(network: Network, db: &db::SharedStore, matches: &clap::ArgMatches) -> Result<ConsensusFork, String> {
let old_consensus_fork = db.consensus_fork()?;
let new_consensus_fork = match (matches.is_present("segwit"), matches.is_present("bitcoin-cash")) {
(false, false) => match &old_consensus_fork {
@ -188,7 +188,7 @@ fn parse_consensus_fork(db: &db::SharedStore, matches: &clap::ArgMatches) -> Res
Ok(match new_consensus_fork {
"segwit" => ConsensusFork::NoFork,
"bitcoin-cash" => ConsensusFork::BitcoinCash(Default::default()),
"bitcoin-cash" => ConsensusFork::BitcoinCash(BitcoinCashConsensusParams::new(network)),
_ => unreachable!("hardcoded above"),
})
}

View File

@ -880,7 +880,8 @@ impl<T> SynchronizationClientCore<T> where T: TaskExecutor {
for (header_index, header) in headers.iter().enumerate() {
// check that this header is direct child of previous header
if &header.raw.previous_header_hash != last_known_hash {
self.peers.misbehaving(peer_index, &format!("Neighbour headers in `headers` message are unlinked: Prev: {}, PrevLink: {}, Curr: {}", last_known_hash.to_reversed_str(), header.raw.previous_header_hash.to_reversed_str(), header.hash.to_reversed_str()));
self.peers.misbehaving(peer_index, &format!("Neighbour headers in `headers` message are unlinked: Prev: {}, PrevLink: {}, Curr: {}",
last_known_hash.to_reversed_str(), header.raw.previous_header_hash.to_reversed_str(), header.hash.to_reversed_str()));
return BlocksHeadersVerificationResult::Skip;
}
@ -893,8 +894,10 @@ impl<T> SynchronizationClientCore<T> where T: TaskExecutor {
self.peers.misbehaving(peer_index, &format!("Provided dead-end block {:?}", header.hash.to_reversed_str()));
return BlocksHeadersVerificationResult::Skip;
},
_ => {
trace!(target: "sync", "Ignoring {} headers from peer#{} - known header in the middle", headers.len(), peer_index);
block_state => {
trace!(target: "sync", "Ignoring {} headers from peer#{} - known ({:?}) header {} at the {}/{} ({}...{})",
headers.len(), peer_index, block_state, header.hash.to_reversed_str(), header_index, headers.len(),
headers[0].hash.to_reversed_str(), headers[headers.len() - 1].hash.to_reversed_str());
self.peers_tasks.useful_peer(peer_index);
return BlocksHeadersVerificationResult::Skip;
},

View File

@ -470,7 +470,7 @@ impl<'a> TransactionPrematureWitness<'a> {
#[cfg(test)]
mod tests {
use chain::{IndexedTransaction, Transaction, TransactionOutput};
use network::{Network, ConsensusParams, ConsensusFork};
use network::{Network, ConsensusParams, ConsensusFork, BitcoinCashConsensusParams};
use script::Builder;
use canon::CanonTransaction;
use error::TransactionError;
@ -492,7 +492,7 @@ mod tests {
assert_eq!(transaction.raw.outputs[0].script_pubkey.len(), 46 + 2);
let consensus = ConsensusParams::new(Network::Mainnet, ConsensusFork::BitcoinCash(Default::default()));
let consensus = ConsensusParams::new(Network::Mainnet, ConsensusFork::BitcoinCash(BitcoinCashConsensusParams::new(Network::Mainnet)));
let checker = TransactionReturnReplayProtection::new(CanonTransaction::new(&transaction), &consensus, consensus.fork.activation_height());
assert_eq!(checker.check(), Err(TransactionError::ReturnReplayProtection));
let checker = TransactionReturnReplayProtection::new(CanonTransaction::new(&transaction), &consensus, consensus.fork.activation_height() - 1);

View File

@ -14,8 +14,8 @@ use constants::{
/// Returns work required for given header for the post-HF Bitcoin Cash block
pub fn work_required_bitcoin_cash(parent_header: IndexedBlockHeader, time: u32, height: u32, store: &BlockHeaderProvider, consensus: &ConsensusParams, fork: &BitcoinCashConsensusParams, max_bits: Compact) -> Compact {
// special processing of Bitcoin Cash difficulty adjustment hardfork (Nov 2017), where difficulty is adjusted after each block
let parent_timestamp = median_timestamp_inclusive(parent_header.hash.clone(), store);
if parent_timestamp >= fork.difficulty_adjustion_time {
// `height` is the height of the new block => comparison is shifted by one
if height.saturating_sub(1) >= fork.difficulty_adjustion_height {
return work_required_bitcoin_cash_adjusted(parent_header, time, height, store, consensus);
}
@ -40,6 +40,7 @@ pub fn work_required_bitcoin_cash(parent_header: IndexedBlockHeader, time: u32,
.expect("parent_header.bits != max_bits; difficulty is max_bits for first RETARGETING_INTERVAL height; RETARGETING_INTERVAL > 7; qed");
let ancient_timestamp = median_timestamp_inclusive(ancient_header.hash(), store);
let parent_timestamp = median_timestamp_inclusive(parent_header.hash.clone(), store);
let timestamp_diff = parent_timestamp.checked_sub(ancient_timestamp).unwrap_or_default();
if timestamp_diff < 43_200 {
// less than 12h => no difficulty change needed
@ -215,7 +216,7 @@ mod tests {
let main_consensus = ConsensusParams::new(Network::Mainnet, ConsensusFork::NoFork);
let uahf_consensus = ConsensusParams::new(Network::Mainnet, ConsensusFork::BitcoinCash(BitcoinCashConsensusParams {
height: 1000,
difficulty_adjustion_time: 0xffffffff,
difficulty_adjustion_height: 0xffffffff,
}));
let mut header_provider = MemoryBlockHeaderProvider::default();
header_provider.insert(BlockHeader {
@ -267,7 +268,7 @@ mod tests {
fn bitcoin_cash_adjusted_difficulty() {
let uahf_consensus = ConsensusParams::new(Network::Mainnet, ConsensusFork::BitcoinCash(BitcoinCashConsensusParams {
height: 1000,
difficulty_adjustion_time: 0xffffffff,
difficulty_adjustion_height: 0xffffffff,
}));