next
This commit is contained in:
parent
787a36549c
commit
3fc8dab8ee
|
@ -43,6 +43,15 @@ pub struct BitcoinCashConsensusParams {
|
||||||
pub monolith_time: u32,
|
pub monolith_time: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
/// ZCash consensus parameters.
|
||||||
|
pub struct ZCashConsensusParams {
|
||||||
|
pub pow_averaging_window: u32,
|
||||||
|
pub pow_max_adjust_down: u32,
|
||||||
|
pub pow_max_adjust_up: u32,
|
||||||
|
pub pow_target_spacing: u32,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
/// Concurrent consensus rule forks.
|
/// Concurrent consensus rule forks.
|
||||||
pub enum ConsensusFork {
|
pub enum ConsensusFork {
|
||||||
|
@ -56,7 +65,7 @@ pub enum ConsensusFork {
|
||||||
/// BUIP-HF Digest for replay protected signature verification across hard forks - https://github.com/Bitcoin-UAHF/spec/blob/master/replay-protected-sighash.md
|
/// BUIP-HF Digest for replay protected signature verification across hard forks - https://github.com/Bitcoin-UAHF/spec/blob/master/replay-protected-sighash.md
|
||||||
BitcoinCash(BitcoinCashConsensusParams),
|
BitcoinCash(BitcoinCashConsensusParams),
|
||||||
/// ZCash.
|
/// ZCash.
|
||||||
ZCash,
|
ZCash(ZCashConsensusParams),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ConsensusParams {
|
impl ConsensusParams {
|
||||||
|
@ -65,19 +74,19 @@ impl ConsensusParams {
|
||||||
Network::Mainnet | Network::Other(_) => ConsensusParams {
|
Network::Mainnet | Network::Other(_) => ConsensusParams {
|
||||||
network: network,
|
network: network,
|
||||||
bip16_time: match fork {
|
bip16_time: match fork {
|
||||||
ConsensusFork::ZCash => 0,
|
ConsensusFork::ZCash(_) => 0,
|
||||||
_ => 1333238400, // Apr 1 2012
|
_ => 1333238400, // Apr 1 2012
|
||||||
},
|
},
|
||||||
bip34_height: match fork {
|
bip34_height: match fork {
|
||||||
ConsensusFork::ZCash => 1,
|
ConsensusFork::ZCash(_) => 1,
|
||||||
_ => 227931, // 000000000000024b89b42a942fe0d9fea3bb44ab7bd1b19115dd6a759c0808b8
|
_ => 227931, // 000000000000024b89b42a942fe0d9fea3bb44ab7bd1b19115dd6a759c0808b8
|
||||||
},
|
},
|
||||||
bip65_height: match fork {
|
bip65_height: match fork {
|
||||||
ConsensusFork::ZCash => 0,
|
ConsensusFork::ZCash(_) => 0,
|
||||||
_ => 388381, // 000000000000000004c2b624ed5d7756c508d90fd0da2c7c679febfa6c4735f0
|
_ => 388381, // 000000000000000004c2b624ed5d7756c508d90fd0da2c7c679febfa6c4735f0
|
||||||
},
|
},
|
||||||
bip66_height: match fork {
|
bip66_height: match fork {
|
||||||
ConsensusFork::ZCash => 0,
|
ConsensusFork::ZCash(_) => 0,
|
||||||
_ => 363725, // 00000000000000000379eaa19dce8c9b722d46ae6a57c2f1a988119488b50931
|
_ => 363725, // 00000000000000000379eaa19dce8c9b722d46ae6a57c2f1a988119488b50931
|
||||||
},
|
},
|
||||||
segwit_deployment: match fork {
|
segwit_deployment: match fork {
|
||||||
|
@ -88,7 +97,7 @@ impl ConsensusParams {
|
||||||
timeout: 1510704000,
|
timeout: 1510704000,
|
||||||
activation: Some(481824),
|
activation: Some(481824),
|
||||||
}),
|
}),
|
||||||
ConsensusFork::BitcoinCash(_) | ConsensusFork::ZCash => None,
|
ConsensusFork::BitcoinCash(_) | ConsensusFork::ZCash(_) => None,
|
||||||
},
|
},
|
||||||
fork: fork,
|
fork: fork,
|
||||||
rule_change_activation_threshold: 1916, // 95%
|
rule_change_activation_threshold: 1916, // 95%
|
||||||
|
@ -104,19 +113,19 @@ impl ConsensusParams {
|
||||||
Network::Testnet => ConsensusParams {
|
Network::Testnet => ConsensusParams {
|
||||||
network: network,
|
network: network,
|
||||||
bip16_time: match fork {
|
bip16_time: match fork {
|
||||||
ConsensusFork::ZCash => 0,
|
ConsensusFork::ZCash(_) => 0,
|
||||||
_ => 1333238400, // Apr 1 2012
|
_ => 1333238400, // Apr 1 2012
|
||||||
},
|
},
|
||||||
bip34_height: match fork {
|
bip34_height: match fork {
|
||||||
ConsensusFork::ZCash => 1,
|
ConsensusFork::ZCash(_) => 1,
|
||||||
_ => 21111, // 0000000023b3a96d3484e5abb3755c413e7d41500f8e2a5c3f0dd01299cd8ef8
|
_ => 21111, // 0000000023b3a96d3484e5abb3755c413e7d41500f8e2a5c3f0dd01299cd8ef8
|
||||||
},
|
},
|
||||||
bip65_height: match fork {
|
bip65_height: match fork {
|
||||||
ConsensusFork::ZCash => 0,
|
ConsensusFork::ZCash(_) => 0,
|
||||||
_ => 581885, // 00000000007f6655f22f98e72ed80d8b06dc761d5da09df0fa1dc4be4f861eb6
|
_ => 581885, // 00000000007f6655f22f98e72ed80d8b06dc761d5da09df0fa1dc4be4f861eb6
|
||||||
},
|
},
|
||||||
bip66_height: match fork {
|
bip66_height: match fork {
|
||||||
ConsensusFork::ZCash => 0,
|
ConsensusFork::ZCash(_) => 0,
|
||||||
_ => 330776, // 000000002104c8c45e99a8853285a3b592602a3ccde2b832481da85e9e4ba182
|
_ => 330776, // 000000002104c8c45e99a8853285a3b592602a3ccde2b832481da85e9e4ba182
|
||||||
},
|
},
|
||||||
segwit_deployment: match fork {
|
segwit_deployment: match fork {
|
||||||
|
@ -127,7 +136,7 @@ impl ConsensusParams {
|
||||||
timeout: 1493596800,
|
timeout: 1493596800,
|
||||||
activation: Some(834624),
|
activation: Some(834624),
|
||||||
}),
|
}),
|
||||||
ConsensusFork::BitcoinCash(_) | ConsensusFork::ZCash => None,
|
ConsensusFork::BitcoinCash(_) | ConsensusFork::ZCash(_) => None,
|
||||||
},
|
},
|
||||||
fork: fork,
|
fork: fork,
|
||||||
rule_change_activation_threshold: 1512, // 75%
|
rule_change_activation_threshold: 1512, // 75%
|
||||||
|
@ -143,19 +152,19 @@ impl ConsensusParams {
|
||||||
Network::Regtest | Network::Unitest => ConsensusParams {
|
Network::Regtest | Network::Unitest => ConsensusParams {
|
||||||
network: network,
|
network: network,
|
||||||
bip16_time: match fork {
|
bip16_time: match fork {
|
||||||
ConsensusFork::ZCash => 0,
|
ConsensusFork::ZCash(_) => 0,
|
||||||
_ => 1333238400, // Apr 1 2012
|
_ => 1333238400, // Apr 1 2012
|
||||||
},
|
},
|
||||||
bip34_height: match fork {
|
bip34_height: match fork {
|
||||||
ConsensusFork::ZCash => 1,
|
ConsensusFork::ZCash(_) => 1,
|
||||||
_ => 100000000, // not activated on regtest
|
_ => 100000000, // not activated on regtest
|
||||||
},
|
},
|
||||||
bip65_height: match fork {
|
bip65_height: match fork {
|
||||||
ConsensusFork::ZCash => 0,
|
ConsensusFork::ZCash(_) => 0,
|
||||||
_ => 1351,
|
_ => 1351,
|
||||||
},
|
},
|
||||||
bip66_height: match fork {
|
bip66_height: match fork {
|
||||||
ConsensusFork::ZCash => 0,
|
ConsensusFork::ZCash(_) => 0,
|
||||||
_ => 1251, // used only in rpc tests
|
_ => 1251, // used only in rpc tests
|
||||||
},
|
},
|
||||||
segwit_deployment: match fork {
|
segwit_deployment: match fork {
|
||||||
|
@ -166,7 +175,7 @@ impl ConsensusParams {
|
||||||
timeout: ::std::u32::MAX,
|
timeout: ::std::u32::MAX,
|
||||||
activation: None,
|
activation: None,
|
||||||
}),
|
}),
|
||||||
ConsensusFork::BitcoinCash(_) | ConsensusFork::ZCash => None,
|
ConsensusFork::BitcoinCash(_) | ConsensusFork::ZCash(_) => None,
|
||||||
},
|
},
|
||||||
fork: fork,
|
fork: fork,
|
||||||
rule_change_activation_threshold: 108, // 75%
|
rule_change_activation_threshold: 108, // 75%
|
||||||
|
@ -212,7 +221,7 @@ impl ConsensusFork {
|
||||||
match *self {
|
match *self {
|
||||||
ConsensusFork::BitcoinCore => 0,
|
ConsensusFork::BitcoinCore => 0,
|
||||||
ConsensusFork::BitcoinCash(ref fork) => fork.height,
|
ConsensusFork::BitcoinCash(ref fork) => fork.height,
|
||||||
ConsensusFork::ZCash => 0,
|
ConsensusFork::ZCash(_) => 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,7 +236,7 @@ impl ConsensusFork {
|
||||||
// size of first fork block must be larger than 1MB
|
// size of first fork block must be larger than 1MB
|
||||||
ConsensusFork::BitcoinCash(ref fork) if height == fork.height => 1_000_001,
|
ConsensusFork::BitcoinCash(ref fork) if height == fork.height => 1_000_001,
|
||||||
ConsensusFork::BitcoinCore | ConsensusFork::BitcoinCash(_) => 0,
|
ConsensusFork::BitcoinCore | ConsensusFork::BitcoinCash(_) => 0,
|
||||||
ConsensusFork::ZCash => 0,
|
ConsensusFork::ZCash(_) => 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,7 +245,7 @@ impl ConsensusFork {
|
||||||
ConsensusFork::BitcoinCash(ref fork) if median_time_past >= fork.monolith_time => 32_000_000,
|
ConsensusFork::BitcoinCash(ref fork) if median_time_past >= fork.monolith_time => 32_000_000,
|
||||||
ConsensusFork::BitcoinCash(ref fork) if height >= fork.height => 8_000_000,
|
ConsensusFork::BitcoinCash(ref fork) if height >= fork.height => 8_000_000,
|
||||||
ConsensusFork::BitcoinCore | ConsensusFork::BitcoinCash(_) => 1_000_000,
|
ConsensusFork::BitcoinCore | ConsensusFork::BitcoinCash(_) => 1_000_000,
|
||||||
ConsensusFork::ZCash => 2_000_000,
|
ConsensusFork::ZCash(_) => 2_000_000,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,13 +254,13 @@ impl ConsensusFork {
|
||||||
// according to REQ-5: max_block_sigops = 20000 * ceil((max(blocksize_bytes, 1000000) / 1000000))
|
// according to REQ-5: max_block_sigops = 20000 * ceil((max(blocksize_bytes, 1000000) / 1000000))
|
||||||
ConsensusFork::BitcoinCash(ref fork) if height >= fork.height =>
|
ConsensusFork::BitcoinCash(ref fork) if height >= fork.height =>
|
||||||
20_000 * (1 + (block_size - 1) / 1_000_000),
|
20_000 * (1 + (block_size - 1) / 1_000_000),
|
||||||
ConsensusFork::BitcoinCore | ConsensusFork::BitcoinCash(_) | ConsensusFork::ZCash => 20_000,
|
ConsensusFork::BitcoinCore | ConsensusFork::BitcoinCash(_) | ConsensusFork::ZCash(_) => 20_000,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn max_block_sigops_cost(&self, height: u32, block_size: usize) -> usize {
|
pub fn max_block_sigops_cost(&self, height: u32, block_size: usize) -> usize {
|
||||||
match *self {
|
match *self {
|
||||||
ConsensusFork::BitcoinCash(_) | ConsensusFork::ZCash =>
|
ConsensusFork::BitcoinCash(_) | ConsensusFork::ZCash(_) =>
|
||||||
self.max_block_sigops(height, block_size) * Self::witness_scale_factor(),
|
self.max_block_sigops(height, block_size) * Self::witness_scale_factor(),
|
||||||
ConsensusFork::BitcoinCore =>
|
ConsensusFork::BitcoinCore =>
|
||||||
80_000,
|
80_000,
|
||||||
|
@ -260,7 +269,7 @@ impl ConsensusFork {
|
||||||
|
|
||||||
pub fn max_block_weight(&self, _height: u32) -> usize {
|
pub fn max_block_weight(&self, _height: u32) -> usize {
|
||||||
match *self {
|
match *self {
|
||||||
ConsensusFork::BitcoinCore | ConsensusFork::ZCash =>
|
ConsensusFork::BitcoinCore | ConsensusFork::ZCash(_) =>
|
||||||
4_000_000,
|
4_000_000,
|
||||||
ConsensusFork::BitcoinCash(_) =>
|
ConsensusFork::BitcoinCash(_) =>
|
||||||
unreachable!("BitcoinCash has no SegWit; weight is only checked with SegWit activated; qed"),
|
unreachable!("BitcoinCash has no SegWit; weight is only checked with SegWit activated; qed"),
|
||||||
|
@ -290,6 +299,43 @@ impl BitcoinCashConsensusParams {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ZCashConsensusParams {
|
||||||
|
pub fn new(network: Network) -> Self {
|
||||||
|
match network {
|
||||||
|
Network::Mainnet | Network::Other(_) => ZCashConsensusParams {
|
||||||
|
pow_averaging_window: 17,
|
||||||
|
pow_max_adjust_down: 32,
|
||||||
|
pow_max_adjust_up: 16,
|
||||||
|
pow_target_spacing: (2.5 * 60.0) as u32,
|
||||||
|
},
|
||||||
|
Network::Testnet => ZCashConsensusParams {
|
||||||
|
pow_averaging_window: 17,
|
||||||
|
pow_max_adjust_down: 32,
|
||||||
|
pow_max_adjust_up: 16,
|
||||||
|
pow_target_spacing: (2.5 * 60.0) as u32,
|
||||||
|
},
|
||||||
|
Network::Regtest | Network::Unitest => ZCashConsensusParams {
|
||||||
|
pow_averaging_window: 17,
|
||||||
|
pow_max_adjust_down: 0,
|
||||||
|
pow_max_adjust_up: 0,
|
||||||
|
pow_target_spacing: (2.5 * 60.0) as u32,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn averaging_window_timespan(&self) -> u32 {
|
||||||
|
self.pow_averaging_window * self.pow_target_spacing
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn min_actual_timespan(&self) -> u32 {
|
||||||
|
(self.averaging_window_timespan() * (100 - self.pow_max_adjust_up)) / 100
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn max_actual_timespan(&self) -> u32 {
|
||||||
|
(self.averaging_window_timespan() * (100 + self.pow_max_adjust_down)) / 100
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::super::Network;
|
use super::super::Network;
|
||||||
|
|
|
@ -11,6 +11,6 @@ mod network;
|
||||||
|
|
||||||
pub use primitives::{hash, compact};
|
pub use primitives::{hash, compact};
|
||||||
|
|
||||||
pub use consensus::{ConsensusParams, ConsensusFork, BitcoinCashConsensusParams};
|
pub use consensus::{ConsensusParams, ConsensusFork, BitcoinCashConsensusParams, ZCashConsensusParams};
|
||||||
pub use deployments::Deployment;
|
pub use deployments::Deployment;
|
||||||
pub use network::{Magic, Network};
|
pub use network::{Magic, Network};
|
||||||
|
|
|
@ -60,9 +60,9 @@ impl Network {
|
||||||
(&ConsensusFork::BitcoinCash(_), Network::Mainnet) => BITCOIN_CASH_MAGIC_MAINNET,
|
(&ConsensusFork::BitcoinCash(_), Network::Mainnet) => BITCOIN_CASH_MAGIC_MAINNET,
|
||||||
(&ConsensusFork::BitcoinCash(_), Network::Testnet) => BITCOIN_CASH_MAGIC_TESTNET,
|
(&ConsensusFork::BitcoinCash(_), Network::Testnet) => BITCOIN_CASH_MAGIC_TESTNET,
|
||||||
(&ConsensusFork::BitcoinCash(_), Network::Regtest) => BITCOIN_CASH_MAGIC_REGTEST,
|
(&ConsensusFork::BitcoinCash(_), Network::Regtest) => BITCOIN_CASH_MAGIC_REGTEST,
|
||||||
(&ConsensusFork::ZCash, Network::Mainnet) => ZCASH_MAGIC_MAINNET,
|
(&ConsensusFork::ZCash(_), Network::Mainnet) => ZCASH_MAGIC_MAINNET,
|
||||||
(&ConsensusFork::ZCash, Network::Testnet) => ZCASH_MAGIC_TESTNET,
|
(&ConsensusFork::ZCash(_), Network::Testnet) => ZCASH_MAGIC_TESTNET,
|
||||||
(&ConsensusFork::ZCash, Network::Regtest) => ZCASH_MAGIC_REGTEST,
|
(&ConsensusFork::ZCash(_), Network::Regtest) => ZCASH_MAGIC_REGTEST,
|
||||||
(_, Network::Mainnet) => MAGIC_MAINNET,
|
(_, Network::Mainnet) => MAGIC_MAINNET,
|
||||||
(_, Network::Testnet) => MAGIC_TESTNET,
|
(_, Network::Testnet) => MAGIC_TESTNET,
|
||||||
(_, Network::Regtest) => MAGIC_REGTEST,
|
(_, Network::Regtest) => MAGIC_REGTEST,
|
||||||
|
@ -73,9 +73,9 @@ impl Network {
|
||||||
|
|
||||||
pub fn max_bits(&self, fork: &ConsensusFork) -> U256 {
|
pub fn max_bits(&self, fork: &ConsensusFork) -> U256 {
|
||||||
match (fork, *self) {
|
match (fork, *self) {
|
||||||
(&ConsensusFork::ZCash, Network::Mainnet) => ZCASH_MAX_BITS_MAINNET.clone(),
|
(&ConsensusFork::ZCash(_), Network::Mainnet) => ZCASH_MAX_BITS_MAINNET.clone(),
|
||||||
(&ConsensusFork::ZCash, Network::Testnet) => ZCASH_MAX_BITS_TESTNET.clone(),
|
(&ConsensusFork::ZCash(_), Network::Testnet) => ZCASH_MAX_BITS_TESTNET.clone(),
|
||||||
(&ConsensusFork::ZCash, Network::Testnet) => ZCASH_MAX_BITS_REGTEST.clone(),
|
(&ConsensusFork::ZCash(_), Network::Testnet) => ZCASH_MAX_BITS_REGTEST.clone(),
|
||||||
(_, Network::Mainnet) | (_, Network::Other(_)) => MAX_BITS_MAINNET.clone(),
|
(_, Network::Mainnet) | (_, Network::Other(_)) => MAX_BITS_MAINNET.clone(),
|
||||||
(_, Network::Testnet) => MAX_BITS_TESTNET.clone(),
|
(_, Network::Testnet) => MAX_BITS_TESTNET.clone(),
|
||||||
(_, Network::Regtest) => MAX_BITS_REGTEST.clone(),
|
(_, Network::Regtest) => MAX_BITS_REGTEST.clone(),
|
||||||
|
@ -85,9 +85,9 @@ impl Network {
|
||||||
|
|
||||||
pub fn port(&self, fork: &ConsensusFork) -> u16 {
|
pub fn port(&self, fork: &ConsensusFork) -> u16 {
|
||||||
match (fork, *self) {
|
match (fork, *self) {
|
||||||
(&ConsensusFork::ZCash, Network::Mainnet) | (&ConsensusFork::ZCash, Network::Other(_)) => 8233,
|
(&ConsensusFork::ZCash(_), Network::Mainnet) | (&ConsensusFork::ZCash(_), Network::Other(_)) => 8233,
|
||||||
(&ConsensusFork::ZCash, Network::Testnet) => 18233,
|
(&ConsensusFork::ZCash(_), Network::Testnet) => 18233,
|
||||||
(&ConsensusFork::ZCash, Network::Regtest) | (&ConsensusFork::ZCash, Network::Unitest) => 18344,
|
(&ConsensusFork::ZCash(_), Network::Regtest) | (&ConsensusFork::ZCash(_), Network::Unitest) => 18344,
|
||||||
(_, Network::Mainnet) | (_, Network::Other(_)) => 8333,
|
(_, Network::Mainnet) | (_, Network::Other(_)) => 8333,
|
||||||
(_, Network::Testnet) => 18333,
|
(_, Network::Testnet) => 18333,
|
||||||
(_, Network::Regtest) | (_, Network::Unitest) => 18444,
|
(_, Network::Regtest) | (_, Network::Unitest) => 18444,
|
||||||
|
@ -105,7 +105,7 @@ impl Network {
|
||||||
pub fn genesis_block(&self, fork: &ConsensusFork) -> Block {
|
pub fn genesis_block(&self, fork: &ConsensusFork) -> Block {
|
||||||
match (fork, *self) {
|
match (fork, *self) {
|
||||||
// TODO
|
// TODO
|
||||||
(&ConsensusFork::ZCash, Network::Mainnet) | (&ConsensusFork::ZCash, Network::Other(_)) => {
|
(&ConsensusFork::ZCash(_), Network::Mainnet) | (&ConsensusFork::ZCash(_), Network::Other(_)) => {
|
||||||
use serialization;
|
use serialization;
|
||||||
use chain;
|
use chain;
|
||||||
use chain::hex::FromHex;
|
use chain::hex::FromHex;
|
||||||
|
@ -114,9 +114,9 @@ impl Network {
|
||||||
let genesis: chain::Block = serialization::deserialize_with_flags(&origin as &[u8], serialization::DESERIALIZE_ZCASH).unwrap();
|
let genesis: chain::Block = serialization::deserialize_with_flags(&origin as &[u8], serialization::DESERIALIZE_ZCASH).unwrap();
|
||||||
genesis
|
genesis
|
||||||
},
|
},
|
||||||
(&ConsensusFork::ZCash, Network::Testnet) =>
|
(&ConsensusFork::ZCash(_), Network::Testnet) =>
|
||||||
"".into(),
|
"".into(),
|
||||||
(&ConsensusFork::ZCash, Network::Regtest) | (&ConsensusFork::ZCash, Network::Unitest) =>
|
(&ConsensusFork::ZCash(_), Network::Regtest) | (&ConsensusFork::ZCash(_), Network::Unitest) =>
|
||||||
"".into(),
|
"".into(),
|
||||||
|
|
||||||
(_, Network::Mainnet) | (_, Network::Other(_)) => "0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a29ab5f49ffff001d1dac2b7c0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000".into(),
|
(_, Network::Mainnet) | (_, Network::Other(_)) => "0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a29ab5f49ffff001d1dac2b7c0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000".into(),
|
||||||
|
|
|
@ -91,7 +91,7 @@ pub fn start(cfg: config::Config) -> Result<(), String> {
|
||||||
|
|
||||||
let SERIALIZE_ZCASH = 0x80000000; // TODO
|
let SERIALIZE_ZCASH = 0x80000000; // TODO
|
||||||
let serialization_flags = match cfg.consensus.fork {
|
let serialization_flags = match cfg.consensus.fork {
|
||||||
ConsensusFork::ZCash => SERIALIZE_ZCASH,
|
ConsensusFork::ZCash(_) => SERIALIZE_ZCASH,
|
||||||
_ => 0,
|
_ => 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -101,11 +101,11 @@ pub fn start(cfg: config::Config) -> Result<(), String> {
|
||||||
outbound_connections: cfg.outbound_connections,
|
outbound_connections: cfg.outbound_connections,
|
||||||
connection: p2p::NetConfig {
|
connection: p2p::NetConfig {
|
||||||
protocol_version: match &cfg.consensus.fork {
|
protocol_version: match &cfg.consensus.fork {
|
||||||
&ConsensusFork::ZCash => ZCASH_PROTOCOL_VERSION,
|
&ConsensusFork::ZCash(_) => ZCASH_PROTOCOL_VERSION,
|
||||||
_ => PROTOCOL_VERSION,
|
_ => PROTOCOL_VERSION,
|
||||||
},
|
},
|
||||||
protocol_minimum: match &cfg.consensus.fork {
|
protocol_minimum: match &cfg.consensus.fork {
|
||||||
&ConsensusFork::ZCash => ZCASH_PROTOCOL_MINIMUM,
|
&ConsensusFork::ZCash(_) => ZCASH_PROTOCOL_MINIMUM,
|
||||||
_ => PROTOCOL_MINIMUM,
|
_ => PROTOCOL_MINIMUM,
|
||||||
},
|
},
|
||||||
magic: cfg.consensus.magic(),
|
magic: cfg.consensus.magic(),
|
||||||
|
|
|
@ -2,7 +2,7 @@ use std::net;
|
||||||
use clap;
|
use clap;
|
||||||
use storage;
|
use storage;
|
||||||
use message::Services;
|
use message::Services;
|
||||||
use network::{Network, ConsensusParams, ConsensusFork, BitcoinCashConsensusParams};
|
use network::{Network, ConsensusParams, ConsensusFork, BitcoinCashConsensusParams, ZCashConsensusParams};
|
||||||
use p2p::InternetProtocol;
|
use p2p::InternetProtocol;
|
||||||
use seednodes::{mainnet_seednodes, testnet_seednodes, bitcoin_cash_seednodes,
|
use seednodes::{mainnet_seednodes, testnet_seednodes, bitcoin_cash_seednodes,
|
||||||
bitcoin_cash_testnet_seednodes, zcash_seednodes};
|
bitcoin_cash_testnet_seednodes, zcash_seednodes};
|
||||||
|
@ -63,7 +63,7 @@ pub fn parse(matches: &clap::ArgMatches) -> Result<Config, String> {
|
||||||
let consensus = ConsensusParams::new(network, consensus_fork);
|
let consensus = ConsensusParams::new(network, consensus_fork);
|
||||||
|
|
||||||
match consensus.fork {
|
match consensus.fork {
|
||||||
ConsensusFork::ZCash => ser::set_default_flags(ser::SERIALIZE_ZCASH),
|
ConsensusFork::ZCash(_) => ser::set_default_flags(ser::SERIALIZE_ZCASH),
|
||||||
_ => (),
|
_ => (),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ pub fn parse(matches: &clap::ArgMatches) -> Result<Config, String> {
|
||||||
let user_agent_suffix = match consensus.fork {
|
let user_agent_suffix = match consensus.fork {
|
||||||
ConsensusFork::BitcoinCore => "",
|
ConsensusFork::BitcoinCore => "",
|
||||||
ConsensusFork::BitcoinCash(_) => "/UAHF",
|
ConsensusFork::BitcoinCash(_) => "/UAHF",
|
||||||
ConsensusFork::ZCash => "",
|
ConsensusFork::ZCash(_) => "",
|
||||||
};
|
};
|
||||||
let user_agent = match network {
|
let user_agent = match network {
|
||||||
Network::Testnet | Network::Mainnet | Network::Unitest | Network::Other(_) => format!("{}{}", USER_AGENT, user_agent_suffix),
|
Network::Testnet | Network::Mainnet | Network::Unitest | Network::Other(_) => format!("{}{}", USER_AGENT, user_agent_suffix),
|
||||||
|
@ -106,7 +106,7 @@ pub fn parse(matches: &clap::ArgMatches) -> Result<Config, String> {
|
||||||
let seednodes: Vec<String> = match matches.value_of("seednode") {
|
let seednodes: Vec<String> = match matches.value_of("seednode") {
|
||||||
Some(s) => vec![s.parse().map_err(|_| "Invalid seednode".to_owned())?],
|
Some(s) => vec![s.parse().map_err(|_| "Invalid seednode".to_owned())?],
|
||||||
None => match (network, &consensus.fork) {
|
None => match (network, &consensus.fork) {
|
||||||
(Network::Mainnet, &ConsensusFork::ZCash) => zcash_seednodes().into_iter().map(Into::into).collect(),
|
(Network::Mainnet, &ConsensusFork::ZCash(_)) => zcash_seednodes().into_iter().map(Into::into).collect(),
|
||||||
(Network::Mainnet, &ConsensusFork::BitcoinCash(_)) => bitcoin_cash_seednodes().into_iter().map(Into::into).collect(),
|
(Network::Mainnet, &ConsensusFork::BitcoinCash(_)) => bitcoin_cash_seednodes().into_iter().map(Into::into).collect(),
|
||||||
(Network::Testnet, &ConsensusFork::BitcoinCash(_)) => bitcoin_cash_testnet_seednodes().into_iter().map(Into::into).collect(),
|
(Network::Testnet, &ConsensusFork::BitcoinCash(_)) => bitcoin_cash_testnet_seednodes().into_iter().map(Into::into).collect(),
|
||||||
(Network::Mainnet, _) => mainnet_seednodes().into_iter().map(Into::into).collect(),
|
(Network::Mainnet, _) => mainnet_seednodes().into_iter().map(Into::into).collect(),
|
||||||
|
@ -131,7 +131,7 @@ pub fn parse(matches: &clap::ArgMatches) -> Result<Config, String> {
|
||||||
let services = match &consensus.fork {
|
let services = match &consensus.fork {
|
||||||
&ConsensusFork::BitcoinCash(_) => services.with_bitcoin_cash(true),
|
&ConsensusFork::BitcoinCash(_) => services.with_bitcoin_cash(true),
|
||||||
&ConsensusFork::BitcoinCore => services.with_witness(true),
|
&ConsensusFork::BitcoinCore => services.with_witness(true),
|
||||||
&ConsensusFork::ZCash => services,
|
&ConsensusFork::ZCash(_) => services,
|
||||||
};
|
};
|
||||||
|
|
||||||
let verification_level = match matches.value_of("verification-level") {
|
let verification_level = match matches.value_of("verification-level") {
|
||||||
|
@ -200,7 +200,7 @@ fn parse_consensus_fork(network: Network, db: &storage::SharedStore, matches: &c
|
||||||
Ok(match new_consensus_fork {
|
Ok(match new_consensus_fork {
|
||||||
"btc" => ConsensusFork::BitcoinCore,
|
"btc" => ConsensusFork::BitcoinCore,
|
||||||
"bch" => ConsensusFork::BitcoinCash(BitcoinCashConsensusParams::new(network)),
|
"bch" => ConsensusFork::BitcoinCash(BitcoinCashConsensusParams::new(network)),
|
||||||
"zcash" => ConsensusFork::ZCash,
|
"zcash" => ConsensusFork::ZCash(ZCashConsensusParams::new(network)),
|
||||||
_ => unreachable!("hardcoded above"),
|
_ => unreachable!("hardcoded above"),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -248,6 +248,7 @@ impl<F> BlockHeaderBuilder<F> where F: Invoke<chain::BlockHeader> {
|
||||||
nonce: self.nonce.into(),
|
nonce: self.nonce.into(),
|
||||||
merkle_root_hash: self.merkle_root,
|
merkle_root_hash: self.merkle_root,
|
||||||
version: self.version,
|
version: self.version,
|
||||||
|
hash_final_sapling_root: None,
|
||||||
equihash_solution: None,
|
equihash_solution: None,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
@ -82,7 +82,7 @@ impl<'a> HeaderEquihashSolution<'a> {
|
||||||
|
|
||||||
fn check(&self) -> Result<(), Error> {
|
fn check(&self) -> Result<(), Error> {
|
||||||
match self.consensus.fork {
|
match self.consensus.fork {
|
||||||
ConsensusFork::ZCash => (),
|
ConsensusFork::ZCash(_) => (),
|
||||||
_ => return Ok(()),
|
_ => return Ok(()),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -321,7 +321,7 @@ impl<'a> TransactionEval<'a> {
|
||||||
};
|
};
|
||||||
let signature_version = match params.fork {
|
let signature_version = match params.fork {
|
||||||
ConsensusFork::BitcoinCash(ref fork) if height >= fork.height => SignatureVersion::ForkId,
|
ConsensusFork::BitcoinCash(ref fork) if height >= fork.height => SignatureVersion::ForkId,
|
||||||
ConsensusFork::BitcoinCore | ConsensusFork::BitcoinCash(_) | ConsensusFork::ZCash => SignatureVersion::Base,
|
ConsensusFork::BitcoinCore | ConsensusFork::BitcoinCash(_) | ConsensusFork::ZCash(_) => SignatureVersion::Base,
|
||||||
};
|
};
|
||||||
|
|
||||||
let verify_checksequence = deployments.csv();
|
let verify_checksequence = deployments.csv();
|
||||||
|
|
|
@ -294,6 +294,7 @@ mod tests {
|
||||||
time: time,
|
time: time,
|
||||||
bits: 0.into(),
|
bits: 0.into(),
|
||||||
nonce: height.into(),
|
nonce: height.into(),
|
||||||
|
hash_final_sapling_root: None,
|
||||||
equihash_solution: None,
|
equihash_solution: None,
|
||||||
};
|
};
|
||||||
previous_header_hash = header.hash();
|
previous_header_hash = header.hash();
|
||||||
|
|
|
@ -81,6 +81,7 @@ mod sigops;
|
||||||
mod timestamp;
|
mod timestamp;
|
||||||
mod work;
|
mod work;
|
||||||
mod work_bch;
|
mod work_bch;
|
||||||
|
mod work_zcash;
|
||||||
|
|
||||||
// pre-verification
|
// pre-verification
|
||||||
mod verify_block;
|
mod verify_block;
|
||||||
|
|
|
@ -23,5 +23,6 @@ pub fn median_timestamp_inclusive(previous_header_hash: H256, store: &BlockHeade
|
||||||
}
|
}
|
||||||
|
|
||||||
timestamps.sort();
|
timestamps.sort();
|
||||||
|
println!("=== timestamps: {}..{}", timestamps[0], timestamps[10]);
|
||||||
timestamps[timestamps.len() / 2]
|
timestamps[timestamps.len() / 2]
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ use chain::{IndexedBlockHeader, BlockHeader};
|
||||||
use network::{Network, ConsensusParams, ConsensusFork};
|
use network::{Network, ConsensusParams, ConsensusFork};
|
||||||
use storage::{BlockHeaderProvider, BlockRef};
|
use storage::{BlockHeaderProvider, BlockRef};
|
||||||
use work_bch::work_required_bitcoin_cash;
|
use work_bch::work_required_bitcoin_cash;
|
||||||
|
use work_zcash::work_required_zcash;
|
||||||
|
|
||||||
use constants::{
|
use constants::{
|
||||||
DOUBLE_SPACING_SECONDS, TARGET_TIMESPAN_SECONDS,
|
DOUBLE_SPACING_SECONDS, TARGET_TIMESPAN_SECONDS,
|
||||||
|
@ -66,6 +67,11 @@ pub fn work_required(parent_hash: H256, time: u32, height: u32, store: &BlockHea
|
||||||
let parent_header = store.block_header(parent_hash.clone().into()).expect("self.height != 0; qed");
|
let parent_header = store.block_header(parent_hash.clone().into()).expect("self.height != 0; qed");
|
||||||
|
|
||||||
match consensus.fork {
|
match consensus.fork {
|
||||||
|
ConsensusFork::ZCash(ref fork) =>
|
||||||
|
return work_required_zcash(IndexedBlockHeader {
|
||||||
|
hash: parent_hash,
|
||||||
|
raw: parent_header
|
||||||
|
}, time, height, store, fork, max_bits),
|
||||||
ConsensusFork::BitcoinCash(ref fork) if height >= fork.height =>
|
ConsensusFork::BitcoinCash(ref fork) if height >= fork.height =>
|
||||||
return work_required_bitcoin_cash(IndexedBlockHeader {
|
return work_required_bitcoin_cash(IndexedBlockHeader {
|
||||||
hash: parent_hash,
|
hash: parent_hash,
|
||||||
|
|
|
@ -172,7 +172,7 @@ fn work_required_bitcoin_cash_adjusted(parent_header: IndexedBlockHeader, time:
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
pub mod tests {
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use primitives::bytes::Bytes;
|
use primitives::bytes::Bytes;
|
||||||
use primitives::hash::H256;
|
use primitives::hash::H256;
|
||||||
|
@ -184,12 +184,16 @@ mod tests {
|
||||||
use super::work_required_bitcoin_cash_adjusted;
|
use super::work_required_bitcoin_cash_adjusted;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct MemoryBlockHeaderProvider {
|
pub struct MemoryBlockHeaderProvider {
|
||||||
pub by_height: Vec<BlockHeader>,
|
pub by_height: Vec<BlockHeader>,
|
||||||
pub by_hash: HashMap<H256, usize>,
|
pub by_hash: HashMap<H256, usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MemoryBlockHeaderProvider {
|
impl MemoryBlockHeaderProvider {
|
||||||
|
pub fn last(&self) -> &BlockHeader {
|
||||||
|
self.by_height.last().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn insert(&mut self, header: BlockHeader) {
|
pub fn insert(&mut self, header: BlockHeader) {
|
||||||
self.by_hash.insert(header.hash(), self.by_height.len());
|
self.by_hash.insert(header.hash(), self.by_height.len());
|
||||||
self.by_height.push(header);
|
self.by_height.push(header);
|
||||||
|
@ -227,6 +231,7 @@ mod tests {
|
||||||
time: 1269211443,
|
time: 1269211443,
|
||||||
bits: 0x207fffff.into(),
|
bits: 0x207fffff.into(),
|
||||||
nonce: 0.into(),
|
nonce: 0.into(),
|
||||||
|
hash_final_sapling_root: None,
|
||||||
equihash_solution: None,
|
equihash_solution: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -287,6 +292,7 @@ mod tests {
|
||||||
time: 1269211443,
|
time: 1269211443,
|
||||||
bits: initial_bits.into(),
|
bits: initial_bits.into(),
|
||||||
nonce: 0.into(),
|
nonce: 0.into(),
|
||||||
|
hash_final_sapling_root: None,
|
||||||
equihash_solution: None,
|
equihash_solution: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,166 @@
|
||||||
|
use primitives::compact::Compact;
|
||||||
|
use primitives::hash::H256;
|
||||||
|
use primitives::bigint::{Uint, U256};
|
||||||
|
use chain::{IndexedBlockHeader, BlockHeader};
|
||||||
|
use network::{Network, ConsensusParams, ZCashConsensusParams};
|
||||||
|
use storage::BlockHeaderProvider;
|
||||||
|
use timestamp::median_timestamp_inclusive;
|
||||||
|
use work::{is_retarget_height, work_required_testnet, work_required_retarget};
|
||||||
|
|
||||||
|
/// Returns work required for given header for the ZCash block
|
||||||
|
pub fn work_required_zcash(parent_header: IndexedBlockHeader, time: u32, height: u32, store: &BlockHeaderProvider, fork: &ZCashConsensusParams, max_bits: Compact) -> Compact {
|
||||||
|
// Find the first block in the averaging interval
|
||||||
|
let mut oldest_hash = parent_header.hash.clone();
|
||||||
|
let mut bits_total: U256 = parent_header.raw.bits.into();
|
||||||
|
for i in 1..fork.pow_averaging_window {
|
||||||
|
let block_number = match height.checked_sub(i + 1) {
|
||||||
|
Some(block_number) => block_number,
|
||||||
|
None => {
|
||||||
|
println!("=== XXX");
|
||||||
|
return max_bits
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
let previous_header = store.block_header(block_number.into()).expect("block_number > 0 && block_number < height; qed");
|
||||||
|
bits_total = bits_total + previous_header.bits.into();
|
||||||
|
oldest_hash = previous_header.hash();
|
||||||
|
}
|
||||||
|
println!("=== bits_total = {:?}", Compact::from_u256(bits_total));
|
||||||
|
let bits_avg = bits_total / fork.pow_averaging_window.into();
|
||||||
|
let parent_mtp = median_timestamp_inclusive(parent_header.hash.clone(), store);
|
||||||
|
let oldest_mtp = median_timestamp_inclusive(oldest_hash, store);
|
||||||
|
calculate_work_required(bits_avg, parent_mtp, oldest_mtp, fork, max_bits)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn calculate_work_required(bits_avg: U256, parent_mtp: u32, oldest_mtp: u32, fork: &ZCashConsensusParams, max_bits: Compact) -> Compact {
|
||||||
|
// Limit adjustment step
|
||||||
|
// Use medians to prevent time-warp attacks
|
||||||
|
let actual_timespan = parent_mtp - oldest_mtp;
|
||||||
|
println!("=== parent_mtp: {}", parent_mtp);
|
||||||
|
println!("=== oldest_mtp: {}", oldest_mtp);
|
||||||
|
println!("=== actual_timespan_0: {}", actual_timespan);
|
||||||
|
let mut actual_timespan = fork.averaging_window_timespan() as i64 +
|
||||||
|
(actual_timespan as i64 - fork.averaging_window_timespan() as i64) / 4;
|
||||||
|
println!("=== actual_timespan_1: {}", actual_timespan);
|
||||||
|
if actual_timespan < fork.min_actual_timespan() as i64 {
|
||||||
|
actual_timespan = fork.min_actual_timespan() as i64;
|
||||||
|
}
|
||||||
|
if actual_timespan > fork.max_actual_timespan() as i64 {
|
||||||
|
actual_timespan = fork.max_actual_timespan() as i64;
|
||||||
|
}
|
||||||
|
println!("=== actual_timespan_2: {}", actual_timespan);
|
||||||
|
// Retarget
|
||||||
|
let actual_timespan = actual_timespan as u32;
|
||||||
|
let mut bits_new = bits_avg / fork.averaging_window_timespan().into();
|
||||||
|
bits_new = bits_new * actual_timespan.into();
|
||||||
|
|
||||||
|
if bits_new > max_bits.into() {
|
||||||
|
return max_bits;
|
||||||
|
}
|
||||||
|
|
||||||
|
bits_new.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use primitives::bytes::Bytes;
|
||||||
|
use primitives::compact::Compact;
|
||||||
|
use primitives::hash::H256;
|
||||||
|
use primitives::bigint::U256;
|
||||||
|
use network::{Network, ZCashConsensusParams, ConsensusFork};
|
||||||
|
use storage::{BlockHeaderProvider, BlockRef};
|
||||||
|
use chain::BlockHeader;
|
||||||
|
use timestamp::median_timestamp_inclusive;
|
||||||
|
use work::work_required;
|
||||||
|
use work_bch::tests::MemoryBlockHeaderProvider;
|
||||||
|
use super::{work_required_zcash, calculate_work_required};
|
||||||
|
|
||||||
|
// original test link:
|
||||||
|
// https://github.com/Bitcoin-ABC/bitcoin-abc/blob/d8eac91f8d16716eed0ad11ccac420122280bb13/src/test/pow_tests.cpp#L193
|
||||||
|
#[test]
|
||||||
|
fn zcash_work_required_works() {
|
||||||
|
let fork = ZCashConsensusParams::new(Network::Mainnet);
|
||||||
|
let max_bits = Network::Mainnet.max_bits(&ConsensusFork::ZCash(fork.clone()));
|
||||||
|
|
||||||
|
let last_block = 2 * fork.pow_averaging_window;
|
||||||
|
let first_block = last_block - fork.pow_averaging_window;
|
||||||
|
|
||||||
|
// insert genesis block
|
||||||
|
let mut header_provider = MemoryBlockHeaderProvider::default();
|
||||||
|
header_provider.insert(BlockHeader {
|
||||||
|
time: 1269211443,
|
||||||
|
bits: Compact::new(0x1e7fffff),
|
||||||
|
version: 0,
|
||||||
|
previous_header_hash: 0.into(),
|
||||||
|
merkle_root_hash: 0.into(),
|
||||||
|
nonce: 0.into(),
|
||||||
|
hash_final_sapling_root: None,
|
||||||
|
equihash_solution: None,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Start with blocks evenly-spaced and equal difficulty
|
||||||
|
for i in 1..last_block+1 {
|
||||||
|
let header = BlockHeader {
|
||||||
|
time: header_provider.last().time + fork.pow_target_spacing,
|
||||||
|
bits: Compact::new(0x1e7fffff),
|
||||||
|
version: 0,
|
||||||
|
previous_header_hash: 0.into(),
|
||||||
|
merkle_root_hash: 0.into(),
|
||||||
|
nonce: 0.into(),
|
||||||
|
hash_final_sapling_root: None,
|
||||||
|
equihash_solution: None,
|
||||||
|
};
|
||||||
|
header_provider.insert(header);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Result should be unchanged, modulo integer division precision loss
|
||||||
|
let mut expected: U256 = Compact::new(0x1e7fffff).into();
|
||||||
|
expected = expected / fork.averaging_window_timespan().into();
|
||||||
|
expected = expected * fork.averaging_window_timespan().into();
|
||||||
|
let actual = work_required_zcash(header_provider.last().clone().into(),
|
||||||
|
0, header_provider.by_height.len() as u32, &header_provider, &fork, max_bits.into());
|
||||||
|
assert_eq!(actual, expected.into());
|
||||||
|
|
||||||
|
// Result should be the same as if last difficulty was used
|
||||||
|
let bits_avg: U256 = header_provider.by_height[last_block as usize].bits.into();
|
||||||
|
let expected = calculate_work_required(bits_avg,
|
||||||
|
median_timestamp_inclusive(header_provider.by_height[last_block as usize].hash(), &header_provider),
|
||||||
|
median_timestamp_inclusive(header_provider.by_height[first_block as usize].hash(), &header_provider),
|
||||||
|
&fork, max_bits.into());
|
||||||
|
let actual = work_required_zcash(header_provider.last().clone().into(),
|
||||||
|
0, header_provider.by_height.len() as u32, &header_provider, &fork, max_bits.into());
|
||||||
|
assert_eq!(actual, expected);
|
||||||
|
|
||||||
|
/*
|
||||||
|
// Result should be unchanged, modulo integer division precision loss
|
||||||
|
let mut bits_expected: U256 = Compact::new(0x1e7fffff).into();
|
||||||
|
bits_expected = bits_expected / fork.averaging_window_timespan().into();
|
||||||
|
bits_expected = bits_expected * fork.averaging_window_timespan().into();
|
||||||
|
assert_eq!(calculate_work_required(bits_expected,
|
||||||
|
median_timestamp_inclusive(header_provider.by_height[last_block as usize].hash(), &header_provider),
|
||||||
|
median_timestamp_inclusive(header_provider.by_height[first_block as usize].hash(), &header_provider),
|
||||||
|
&fork, max_bits.into()), bits_expected.into());
|
||||||
|
|
||||||
|
// Randomise the final block time (plus 1 to ensure it is always different)
|
||||||
|
use std::rand::{task_rng, Rng};
|
||||||
|
header_provider.by_height[last_block].time += task_rng().gen_range(1, fork.pow_target_spacing / 2);
|
||||||
|
|
||||||
|
// Result should be the same as if last difficulty was used
|
||||||
|
bits_expected = header_provider.by_height[last_block].bits;
|
||||||
|
assert_eq!(calculate_work_required(bits_expected,
|
||||||
|
median_timestamp_inclusive(header_provider.by_height[last_block as usize].hash(), &header_provider),
|
||||||
|
median_timestamp_inclusive(header_provider.by_height[first_block as usize].hash(), &header_provider),
|
||||||
|
&fork, max_bits.into()), bits_expected.into());
|
||||||
|
|
||||||
|
// Result should be the same as if last difficulty was used
|
||||||
|
bnAvg.SetCompact(blocks[lastBlk].nBits);
|
||||||
|
EXPECT_EQ(CalculateNextWorkRequired(bnAvg,
|
||||||
|
blocks[lastBlk].GetMedianTimePast(),
|
||||||
|
blocks[firstBlk].GetMedianTimePast(),
|
||||||
|
params),
|
||||||
|
GetNextWorkRequired(&blocks[lastBlk], nullptr, params));
|
||||||
|
// Result should not be unchanged
|
||||||
|
EXPECT_NE(0x1e7fffff, GetNextWorkRequired(&blocks[lastBlk], nullptr, params));*/
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue