diff --git a/network/src/consensus.rs b/network/src/consensus.rs index d24c1d13..637e7f76 100644 --- a/network/src/consensus.rs +++ b/network/src/consensus.rs @@ -7,11 +7,14 @@ pub struct ConsensusParams { /// Time when BIP16 becomes active. /// See https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki pub bip16_time: u32, + /// Block height at which BIP34 becomes active. + /// See https://github.com/bitcoin/bips/blob/master/bip-0034.mediawiki + pub bip34_height: u32, /// Block height at which BIP65 becomes active. /// See https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki pub bip65_height: u32, /// Block height at which BIP65 becomes active. - /// See https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki + /// See https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki pub bip66_height: u32, } @@ -20,18 +23,21 @@ impl ConsensusParams { match magic { Magic::Mainnet | Magic::Other(_) => ConsensusParams { bip16_time: 1333238400, // Apr 1 2012 + bip34_height: 227931, // 000000000000024b89b42a942fe0d9fea3bb44ab7bd1b19115dd6a759c0808b8 bip65_height: 388381, // 000000000000000004c2b624ed5d7756c508d90fd0da2c7c679febfa6c4735f0 bip66_height: 363725, // 00000000000000000379eaa19dce8c9b722d46ae6a57c2f1a988119488b50931 }, Magic::Testnet => ConsensusParams { bip16_time: 1333238400, // Apr 1 2012 + bip34_height: 21111, // 0000000023b3a96d3484e5abb3755c413e7d41500f8e2a5c3f0dd01299cd8ef8 bip65_height: 581885, // 00000000007f6655f22f98e72ed80d8b06dc761d5da09df0fa1dc4be4f861eb6 bip66_height: 330776, // 000000002104c8c45e99a8853285a3b592602a3ccde2b832481da85e9e4ba182 }, Magic::Regtest | Magic::Unitest => ConsensusParams { bip16_time: 1333238400, // Apr 1 2012 + bip34_height: 100000000, // not activated on regtest bip65_height: 1351, - bip66_height: 1251, + bip66_height: 1251, // used only in rpc tests }, } } @@ -47,6 +53,13 @@ mod tests { use super::super::Magic; use super::ConsensusParams; + #[test] + fn test_consensus_params_bip34_height() { + assert_eq!(ConsensusParams::with_magic(Magic::Mainnet).bip34_height, 227931); + assert_eq!(ConsensusParams::with_magic(Magic::Testnet).bip34_height, 21111); + assert_eq!(ConsensusParams::with_magic(Magic::Regtest).bip34_height, 100000000); + } + #[test] fn test_consensus_params_bip65_height() { assert_eq!(ConsensusParams::with_magic(Magic::Mainnet).bip65_height, 388381); diff --git a/verification/src/accept_header.rs b/verification/src/accept_header.rs index 7bbbf7e5..d6682890 100644 --- a/verification/src/accept_header.rs +++ b/verification/src/accept_header.rs @@ -1,7 +1,6 @@ -use network::Magic; +use network::{Magic, ConsensusParams}; use db::BlockHeaderProvider; use canon::CanonHeader; -use constants::MIN_BLOCK_VERSION; use error::Error; use work::work_required; use timestamp::median_timestamp; @@ -14,9 +13,10 @@ pub struct HeaderAcceptor<'a> { impl<'a> HeaderAcceptor<'a> { pub fn new(store: &'a BlockHeaderProvider, network: Magic, header: CanonHeader<'a>, height: u32) -> Self { + let params = network.consensus_params(); HeaderAcceptor { // TODO: check last 1000 blocks instead of hardcoding the value - version: HeaderVersion::new(header, MIN_BLOCK_VERSION), + version: HeaderVersion::new(header, height, params), work: HeaderWork::new(header, store, height, network), median_timestamp: HeaderMedianTimestamp::new(header, store, network), } @@ -30,21 +30,27 @@ impl<'a> HeaderAcceptor<'a> { } } +/// Conforms to BIP90 +/// https://github.com/bitcoin/bips/blob/master/bip-0090.mediawiki pub struct HeaderVersion<'a> { header: CanonHeader<'a>, - min_version: u32, + height: u32, + consensus_params: ConsensusParams, } impl<'a> HeaderVersion<'a> { - fn new(header: CanonHeader<'a>, min_version: u32) -> Self { + fn new(header: CanonHeader<'a>, height: u32, consensus_params: ConsensusParams) -> Self { HeaderVersion { header: header, - min_version: min_version, + height: height, + consensus_params: consensus_params, } } fn check(&self) -> Result<(), Error> { - if self.header.raw.version < self.min_version { + if (self.header.raw.version < 2 && self.height >= self.consensus_params.bip34_height) || + (self.header.raw.version < 3 && self.height >= self.consensus_params.bip65_height) || + (self.header.raw.version < 4 && self.height >= self.consensus_params.bip66_height) { Err(Error::OldVersionBlock) } else { Ok(()) diff --git a/verification/src/constants.rs b/verification/src/constants.rs index 9c8faab9..6b96d732 100644 --- a/verification/src/constants.rs +++ b/verification/src/constants.rs @@ -6,7 +6,6 @@ pub const MAX_BLOCK_SIZE: usize = 1_000_000; pub const MAX_BLOCK_SIGOPS: usize = 20_000; pub const MIN_COINBASE_SIZE: usize = 2; pub const MAX_COINBASE_SIZE: usize = 100; -pub const MIN_BLOCK_VERSION: u32 = 0; pub const RETARGETING_FACTOR: u32 = 4; pub const TARGET_SPACING_SECONDS: u32 = 10 * 60;