Generalize the Consensus Infrastructure (#883)

* Split out Consensus
* Supply ImportQueue through network-service
  - simplify ImportQueue.import_blocks
  - remove Deadlock on import_block
  - Adding Verifier-Trait
  - Implement import_queue provisioning in service; allow cli to import
* Allow to actually customize import queue
* Consensus Gossip: Cache Message hash per Topic
This commit is contained in:
Benjamin Kampmann
2018-10-16 13:40:33 +02:00
committed by GitHub
parent a24e61cb29
commit ac4bcf879f
61 changed files with 1937 additions and 3306 deletions
+17 -11
View File
@@ -20,7 +20,7 @@ use std::sync::Arc;
use std::time;
use parking_lot::RwLock;
use rustc_hex::ToHex;
use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, Hash, HashFor, NumberFor, As, Zero};
use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, NumberFor, As, Zero};
use runtime_primitives::generic::BlockId;
use network_libp2p::{NodeIndex, Severity};
use codec::{Encode, Decode};
@@ -181,15 +181,15 @@ impl<'a, B: BlockT + 'a, H: ExHashT + 'a> Context<B> for ProtocolContext<'a, B,
pub(crate) struct ContextData<B: BlockT, H: ExHashT> {
// All connected peers
peers: RwLock<HashMap<NodeIndex, Peer<B, H>>>,
chain: Arc<Client<B>>,
pub chain: Arc<Client<B>>,
}
impl<B: BlockT, S: Specialization<B>, H: ExHashT> Protocol<B, S, H> {
/// Create a new instance.
pub fn new(
pub fn new<I: 'static + ImportQueue<B>>(
config: ProtocolConfig,
chain: Arc<Client<B>>,
import_queue: Arc<ImportQueue<B>>,
import_queue: Arc<I>,
on_demand: Option<Arc<OnDemandService<B>>>,
transaction_pool: Arc<TransactionPool<H, B>>,
specialization: S,
@@ -373,7 +373,19 @@ impl<B: BlockT, S: Specialization<B>, H: ExHashT> Protocol<B, S, H> {
trace!(target: "sync", "BlockResponse {} from {} with {} blocks{}",
response.id, peer, response.blocks.len(), blocks_range);
self.sync.write().on_block_data(&mut ProtocolContext::new(&self.context_data, io), peer, request, response);
// import_queue.import_blocks also acquires sync.write();
// Break the cycle by doing these separately from the outside;
let new_blocks = {
let mut sync = self.sync.write();
sync.on_block_data(&mut ProtocolContext::new(&self.context_data, io), peer, request, response)
};
if let Some((origin, new_blocks)) = new_blocks {
let import_queue = self.sync.read().import_queue();
import_queue.import_blocks(origin, new_blocks);
}
}
/// Perform time based maintenance.
@@ -704,12 +716,6 @@ fn send_message<B: BlockT, H: ExHashT>(peers: &RwLock<HashMap<NodeIndex, Peer<B,
io.send(who, message.encode());
}
/// Hash a message.
pub(crate) fn hash_message<B: BlockT>(message: &Message<B>) -> B::Hash {
let data = message.encode();
HashFor::<B>::hash(&data)
}
/// Construct a simple protocol that is composed of several sub protocols.
/// Each "sub protocol" needs to implement `Specialization` and needs to provide a `new()` function.
/// For more fine grained implementations, this macro is not usable.