always ask for witness when requesting b/tx on core chain

This commit is contained in:
Svyatoslav Nikolsky 2018-11-07 09:34:30 +03:00
parent b68f5130e1
commit 9e07969d44
4 changed files with 21 additions and 33 deletions

View File

@ -170,6 +170,14 @@ impl ConsensusFork {
4 4
} }
/// Returns true if SegWit is possible on this chain.
pub fn is_segwit_possible(&self) -> bool {
match *self {
ConsensusFork::BitcoinCore => true,
ConsensusFork::BitcoinCash(_) => false,
}
}
pub fn activation_height(&self) -> u32 { pub fn activation_height(&self) -> u32 {
match *self { match *self {
ConsensusFork::BitcoinCore => 0, ConsensusFork::BitcoinCore => 0,

View File

@ -110,7 +110,7 @@ pub fn create_local_sync_node(consensus: ConsensusParams, db: storage::SharedSto
let memory_pool = Arc::new(RwLock::new(MemoryPool::new())); let memory_pool = Arc::new(RwLock::new(MemoryPool::new()));
let sync_state = SynchronizationStateRef::new(SynchronizationState::with_storage(db.clone())); let sync_state = SynchronizationStateRef::new(SynchronizationState::with_storage(db.clone()));
let sync_chain = SyncChain::new(db.clone(), consensus.clone(), memory_pool.clone()); let sync_chain = SyncChain::new(db.clone(), consensus.clone(), memory_pool.clone());
if sync_chain.is_segwit_active() { if sync_chain.is_segwit_possible() {
peers.require_peer_services(Services::default().with_witness(true)); peers.require_peer_services(Services::default().with_witness(true));
} }

View File

@ -9,7 +9,6 @@ use primitives::bytes::Bytes;
use primitives::hash::H256; use primitives::hash::H256;
use utils::{BestHeadersChain, BestHeadersChainInformation, HashQueueChain, HashPosition}; use utils::{BestHeadersChain, BestHeadersChainInformation, HashQueueChain, HashPosition};
use types::{BlockHeight, StorageRef, MemoryPoolRef}; use types::{BlockHeight, StorageRef, MemoryPoolRef};
use verification::Deployments;
/// Index of 'verifying' queue /// Index of 'verifying' queue
const VERIFYING_QUEUE: usize = 0; const VERIFYING_QUEUE: usize = 0;
@ -106,8 +105,6 @@ pub struct Chain {
best_storage_block: storage::BestBlock, best_storage_block: storage::BestBlock,
/// Local blocks storage /// Local blocks storage
storage: StorageRef, storage: StorageRef,
/// Consensus params.
consensus: ConsensusParams,
/// In-memory queue of blocks hashes /// In-memory queue of blocks hashes
hash_chain: HashQueueChain, hash_chain: HashQueueChain,
/// In-memory queue of blocks headers /// In-memory queue of blocks headers
@ -118,10 +115,9 @@ pub struct Chain {
memory_pool: MemoryPoolRef, memory_pool: MemoryPoolRef,
/// Blocks that have been marked as dead-ends /// Blocks that have been marked as dead-ends
dead_end_blocks: HashSet<H256>, dead_end_blocks: HashSet<H256>,
/// Deployments cache /// Is SegWit is possible on this chain? SegWit inventory types are used when block/tx-es are
deployments: Deployments, /// requested and this flag is true.
/// Is SegWit active? is_segwit_possible: bool,
is_segwit_active: bool,
} }
impl BlockState { impl BlockState {
@ -152,21 +148,18 @@ impl Chain {
.expect("storage with genesis block is required"); .expect("storage with genesis block is required");
let best_storage_block = storage.best_block(); let best_storage_block = storage.best_block();
let best_storage_block_hash = best_storage_block.hash.clone(); let best_storage_block_hash = best_storage_block.hash.clone();
let deployments = Deployments::new(); let is_segwit_possible = consensus.fork.is_segwit_possible();
let is_segwit_active = deployments.segwit(best_storage_block.number, storage.as_block_header_provider(), &consensus);
Chain { Chain {
genesis_block_hash: genesis_block_hash, genesis_block_hash: genesis_block_hash,
best_storage_block: best_storage_block, best_storage_block: best_storage_block,
storage: storage, storage: storage,
consensus: consensus,
hash_chain: HashQueueChain::with_number_of_queues(NUMBER_OF_QUEUES), hash_chain: HashQueueChain::with_number_of_queues(NUMBER_OF_QUEUES),
headers_chain: BestHeadersChain::new(best_storage_block_hash), headers_chain: BestHeadersChain::new(best_storage_block_hash),
verifying_transactions: LinkedHashMap::new(), verifying_transactions: LinkedHashMap::new(),
memory_pool: memory_pool, memory_pool: memory_pool,
dead_end_blocks: HashSet::new(), dead_end_blocks: HashSet::new(),
deployments: deployments, is_segwit_possible,
is_segwit_active: is_segwit_active,
} }
} }
@ -193,8 +186,8 @@ impl Chain {
} }
/// Is segwit active /// Is segwit active
pub fn is_segwit_active(&self) -> bool { pub fn is_segwit_possible(&self) -> bool {
self.is_segwit_active self.is_segwit_possible
} }
/// Get number of blocks in given state /// Get number of blocks in given state
@ -367,7 +360,6 @@ impl Chain {
// remember new best block hash // remember new best block hash
self.best_storage_block = self.storage.as_store().best_block(); self.best_storage_block = self.storage.as_store().best_block();
self.is_segwit_active = self.deployments.segwit(self.best_storage_block.number, self.storage.as_block_header_provider(), &self.consensus);
// remove inserted block + handle possible reorganization in headers chain // remove inserted block + handle possible reorganization in headers chain
// TODO: mk, not sure if we need both of those params // TODO: mk, not sure if we need both of those params
@ -403,7 +395,6 @@ impl Chain {
// remember new best block hash // remember new best block hash
self.best_storage_block = self.storage.best_block(); self.best_storage_block = self.storage.best_block();
self.is_segwit_active = self.deployments.segwit(self.best_storage_block.number, self.storage.as_block_header_provider(), &self.consensus);
// remove inserted block + handle possible reorganization in headers chain // remove inserted block + handle possible reorganization in headers chain
// TODO: mk, not sure if we need both of those params // TODO: mk, not sure if we need both of those params

View File

@ -6,7 +6,7 @@ use futures::Future;
use parking_lot::Mutex; use parking_lot::Mutex;
use time::precise_time_s; use time::precise_time_s;
use chain::{IndexedBlockHeader, IndexedTransaction, Transaction, IndexedBlock}; use chain::{IndexedBlockHeader, IndexedTransaction, Transaction, IndexedBlock};
use message::{types, Services}; use message::types;
use message::common::{InventoryType, InventoryVector}; use message::common::{InventoryType, InventoryVector};
use miner::transaction_fee_rate; use miner::transaction_fee_rate;
use primitives::hash::H256; use primitives::hash::H256;
@ -226,8 +226,7 @@ impl<T> ClientCore for SynchronizationClientCore<T> where T: TaskExecutor {
} }
// else ask for all unknown transactions and blocks // else ask for all unknown transactions and blocks
let is_segwit_active = self.chain.is_segwit_active(); let is_segwit_possible = self.chain.is_segwit_possible();
let ask_for_witness = is_segwit_active && self.peers.is_segwit_enabled(peer_index);
let unknown_inventory: Vec<_> = message.inventory.into_iter() let unknown_inventory: Vec<_> = message.inventory.into_iter()
.filter(|item| { .filter(|item| {
match item.inv_type { match item.inv_type {
@ -258,7 +257,7 @@ impl<T> ClientCore for SynchronizationClientCore<T> where T: TaskExecutor {
// we are not synchronizing => // we are not synchronizing =>
// 1) either segwit is active and we are connected to segwit-enabled nodes => we could ask for witness // 1) either segwit is active and we are connected to segwit-enabled nodes => we could ask for witness
// 2) or segwit is inactive => we shall not ask for witness // 2) or segwit is inactive => we shall not ask for witness
.map(|item| if !ask_for_witness { .map(|item| if !is_segwit_possible {
item item
} else { } else {
match item.inv_type { match item.inv_type {
@ -973,8 +972,8 @@ impl<T> SynchronizationClientCore<T> where T: TaskExecutor {
let chunk_size = min(limits.max_blocks_in_request, max(hashes.len() as BlockHeight, limits.min_blocks_in_request)); let chunk_size = min(limits.max_blocks_in_request, max(hashes.len() as BlockHeight, limits.min_blocks_in_request));
let last_peer_index = peers.len() - 1; let last_peer_index = peers.len() - 1;
let mut tasks: Vec<Task> = Vec::new(); let mut tasks: Vec<Task> = Vec::new();
let is_segwit_active = self.chain.is_segwit_active(); let is_segwit_possible = self.chain.is_segwit_possible();
let inv_type = if is_segwit_active { InventoryType::MessageWitnessBlock } else { InventoryType::MessageBlock }; let inv_type = if is_segwit_possible { InventoryType::MessageWitnessBlock } else { InventoryType::MessageBlock };
for (peer_index, peer) in peers.into_iter().enumerate() { for (peer_index, peer) in peers.into_iter().enumerate() {
// we have to request all blocks => we will request last peer for all remaining blocks // we have to request all blocks => we will request last peer for all remaining blocks
let peer_chunk_size = if peer_index == last_peer_index { hashes.len() } else { min(hashes.len(), chunk_size as usize) }; let peer_chunk_size = if peer_index == last_peer_index { hashes.len() } else { min(hashes.len(), chunk_size as usize) };
@ -1073,9 +1072,6 @@ impl<T> SynchronizationClientCore<T> where T: TaskExecutor {
// update block processing speed // update block processing speed
self.block_speed_meter.checkpoint(); self.block_speed_meter.checkpoint();
// remember if SegWit was active before this block
let segwit_was_active = self.chain.is_segwit_active();
// remove flags // remove flags
let needs_relay = !self.do_not_relay.remove(block.hash()); let needs_relay = !self.do_not_relay.remove(block.hash());
@ -1096,13 +1092,6 @@ impl<T> SynchronizationClientCore<T> where T: TaskExecutor {
// update shared state // update shared state
self.shared_state.update_best_storage_block_height(self.chain.best_storage_block().number); self.shared_state.update_best_storage_block_height(self.chain.best_storage_block().number);
// if SegWit activated after this block insertion:
// 1) no more connections to !NODE_WITNESS nodes
// 2) disconnect from all nodes without NODE_WITNESS support
if !segwit_was_active && self.chain.is_segwit_active() {
self.peers.require_peer_services(Services::default().with_witness(true));
}
// notify listener // notify listener
if let Some(best_block_hash) = insert_result.canonized_blocks_hashes.last() { if let Some(best_block_hash) = insert_result.canonized_blocks_hashes.last() {
if let Some(ref listener) = self.listener { if let Some(ref listener) = self.listener {