From 95255d0f58a7db40699c909e81b1711ca4f60766 Mon Sep 17 00:00:00 2001 From: debris Date: Thu, 27 Apr 2017 15:58:16 +0200 Subject: [PATCH] versionbits in progress --- db/src/block_iterator.rs | 29 +++++++++++++++++++ db/src/lib.rs | 12 ++++---- verification/src/versionbits.rs | 50 +++++++++++++++++++++++++-------- 3 files changed, 74 insertions(+), 17 deletions(-) create mode 100644 db/src/block_iterator.rs diff --git a/db/src/block_iterator.rs b/db/src/block_iterator.rs new file mode 100644 index 00000000..c288cc0f --- /dev/null +++ b/db/src/block_iterator.rs @@ -0,0 +1,29 @@ +use chain::BlockHeader; +use {BlockRef, BlockHeaderProvider}; + +pub struct BlockIterator<'a> { + block: u32, + period: u32, + headers: &'a BlockHeaderProvider, +} + +impl<'a> BlockIterator<'a> { + pub fn new(block: u32, period: u32, headers: &'a BlockHeaderProvider) -> Self { + BlockIterator { + block: block, + period: period, + headers: headers, + } + } +} + +impl<'a> Iterator for BlockIterator<'a> { + type Item = (u32, BlockHeader); + + fn next(&mut self) -> Option { + let result = self.headers.block_header(BlockRef::Number(self.block)); + let block = self.block; + self.block += self.period; + result.map(|header| (block, header)) + } +} diff --git a/db/src/lib.rs b/db/src/lib.rs index 7a002e28..4f9e12ba 100644 --- a/db/src/lib.rs +++ b/db/src/lib.rs @@ -13,13 +13,14 @@ extern crate chain; pub mod kv; mod best_block; mod block_ancestors; +mod block_chain; +mod block_chain_db; +mod block_impls; +mod block_iterator; mod block_origin; mod block_provider; mod block_ref; -mod block_chain; -mod block_chain_db; mod error; -mod block_impls; mod store; mod transaction_meta; mod transaction_provider; @@ -28,11 +29,12 @@ pub use primitives::{hash, bytes}; pub use best_block::BestBlock; pub use block_ancestors::BlockAncestors; +pub use block_chain::{BlockChain, ForkChain, Forkable}; +pub use block_chain_db::{BlockChainDatabase, ForkChainDatabase}; +pub use block_iterator::BlockIterator; pub use block_origin::{BlockOrigin, SideChainOrigin}; pub use block_provider::{BlockHeaderProvider, BlockProvider, IndexedBlockProvider}; pub use block_ref::BlockRef; -pub use block_chain::{BlockChain, ForkChain, Forkable}; -pub use block_chain_db::{BlockChainDatabase, ForkChainDatabase}; pub use error::Error; pub use store::{AsSubstore, Store, SharedStore, CanonStore}; pub use transaction_meta::TransactionMeta; diff --git a/verification/src/versionbits.rs b/verification/src/versionbits.rs index cdf832cd..cd7ce358 100644 --- a/verification/src/versionbits.rs +++ b/verification/src/versionbits.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use network::Magic; use hash::H256; use chain::BlockHeader; -use db::{BlockHeaderProvider, BlockProvider, BlockRef, BlockAncestors}; +use db::{BlockHeaderProvider, BlockProvider, BlockRef, BlockAncestors, BlockIterator}; use timestamp::median_timestamp; const VERSIONBITS_TOP_MASK: u32 = 0xe0000000; @@ -17,23 +17,35 @@ pub enum ThresholdState { Failed, } +impl Default for ThresholdState { + fn default() -> Self { + ThresholdState::Defined + } +} + pub struct ThresholdConditionCache { map: HashMap<&'static str, HashMap>, } #[derive(Debug, Clone, Copy)] pub struct Condition { + /// Deployment's name pub name: &'static str, + /// Bit pub bit: u8, + /// Start time pub start_time: u32, + /// Timeout pub timeout: u32, + /// Activation block number (if already activated) + pub activation: Option, } impl Condition { pub fn csv(network: Magic) -> Option { - let (start_time, timeout) = match network { - Magic::Mainnet => (1462060800, 1493596800), - Magic::Testnet => (1456790400, 1493596800), + let (start_time, timeout, activation) = match network { + Magic::Mainnet => (1462060800, 1493596800, Some(770112)), + Magic::Testnet => (1456790400, 1493596800, Some(419328)), _ => { return None } }; @@ -42,15 +54,16 @@ impl Condition { bit: 0, start_time: start_time, timeout: timeout, + activation: activation, }; Some(condition) } pub fn segwit(network: Magic) -> Option { - let (start_time, timeout) = match network { - Magic::Mainnet => (1479168000, 1510704000), - Magic::Testnet => (1462060800, 1493596800), + let (start_time, timeout, activation) = match network { + Magic::Mainnet => (1479168000, 1510704000, None), + Magic::Testnet => (1462060800, 1493596800, Some(834624)), _ => { return None }, }; @@ -59,6 +72,7 @@ impl Condition { bit: 1, start_time: start_time, timeout: timeout, + activation: activation, }; Some(condition) @@ -69,12 +83,17 @@ impl Condition { } } -pub fn threshold_state(cache: &mut ThresholdConditionCache, condition: Condition, block: &H256, headers: &BlockProvider) -> ThresholdState { +pub fn threshold_state(cache: &mut ThresholdConditionCache, condition: Condition, number: u32, headers: &BlockHeaderProvider, network: Magic) -> ThresholdState { + if let Some(activation) = condition.activation { + if activation <= number { + return ThresholdState::Active; + } + } // A block's state is always the same as that of the first of its period, so it is computed based on a // pindexPrev whose height equals a multiple of nPeriod - 1. // get number of the first block in the period - let number = 0; + let number = first_of_the_period(number); { let condition_cache = cache.map.get(condition.name).expect("condition cache expected to be known"); @@ -83,7 +102,13 @@ pub fn threshold_state(cache: &mut ThresholdConditionCache, condition: Condition } } - unimplemented!(); + // TODO: get proper start number + + let (block_number, state) = ThresholdConditionIterator::new(condition, headers, number, network) + .last() + .unwrap_or_else(|| (number, ThresholdState::default())); + + state } fn first_of_the_period(block: u32) -> u32 { @@ -118,7 +143,7 @@ impl<'a> ThresholdConditionIterator<'a> { } impl<'a> Iterator for ThresholdConditionIterator<'a> { - type Item = ThresholdState; + type Item = (u32, ThresholdState); fn next(&mut self) -> Option { let header = match self.blocks.block_header(BlockRef::Number(self.to_check)) { @@ -155,7 +180,8 @@ impl<'a> Iterator for ThresholdConditionIterator<'a> { } } + let block_number = self.to_check; self.to_check += 2016; - Some(self.last_state) + Some((block_number, self.last_state)) } }