Minimal switch of substrate-node to GRANDPA /Aura (#1128)

* add beginnings of SRML grandpa library

* get srml-grandpa compiling

* tests for srml-grandpa

* add optional session integration to grandpa SRML

* start integration into node runtime

* Allow extracting pending change from header digest

* Make it compile on wasm

* make tests compile again

* Move Authority Key fetching into service, simplify service factory construction

* Generalize Authority Consensus Setup system

* Add Authority Setup Docs

* Allow CLI params to be extensible

 - move params to structopts
 - split parsing and default command execution
 - add custom config to node
 - extended parsing of custom config
 - extending params via structop's flatten

* Minor fixes on cli extension params:
 - added docs
 - re-add actual app name, rather than node-name
 - make strategy and subcommand optional

* better cli params

* synchronize GRANDPA and normal node authorities

* Implement grandpa::network for gossip consensus

* run_grandpa in Node

* Fix missed merge error

* Integrate grandpa import queue

* more specific type def

* link up linkhalf and import block

* make grandpa future send

* get compiling

* Fix new params convention and license header

* get it running

* rebuild node runtime WASM

* change logging level

* Update node/cli/src/params.rs

Co-Authored-By: rphmeier <rphmeier@gmail.com>

* Update node/cli/src/params.rs

Co-Authored-By: rphmeier <rphmeier@gmail.com>

* Update node/cli/src/lib.rs

Co-Authored-By: rphmeier <rphmeier@gmail.com>

* Update node/runtime/src/lib.rs

Co-Authored-By: rphmeier <rphmeier@gmail.com>

* Update node/cli/src/lib.rs

Co-Authored-By: rphmeier <rphmeier@gmail.com>

* Clean up and Fixme for mutable config

* Move GrandpaService Integration into grandpa, feature gated but on per default

* Fixing grandpa runtime module test

* Update wasm runtime hashes for tests

* GRANDPA: use post-header hash when logging scheduled changes

* add an extra bit of logging to authorities

* fixing missing constrain

* remove old code

* move `NewAuthorities` to an event in srml-grandpa

* fix node-executor tests to use grandpa log

* Remove GossipConsensus from tests, use newly provided sync-feature, fixes tests

* Update to latest wasm runtimes

* address grumbles

* address grumbles

* only derive deserialize when using std

* Clean up use of Deserialize
This commit is contained in:
Robert Habermeier
2018-11-21 18:42:50 +01:00
committed by GitHub
parent 84da9d4a02
commit 11fe84a742
59 changed files with 1694 additions and 696 deletions
+3 -2
View File
@@ -87,14 +87,15 @@ pub fn export_blocks<F, E, W>(config: FactoryFullConfiguration<F>, exit: E, mut
}
/// Import blocks from a binary stream.
pub fn import_blocks<F, E, R>(config: FactoryFullConfiguration<F>, exit: E, mut input: R) -> error::Result<()>
pub fn import_blocks<F, E, R>(mut config: FactoryFullConfiguration<F>, exit: E, mut input: R) -> error::Result<()>
where F: ServiceFactory, E: Future<Item=(),Error=()> + Send + 'static, R: Read,
{
struct DummyLink;
impl<B: Block> Link<B> for DummyLink { }
let client = new_client::<F>(&config)?;
let queue = components::FullComponents::<F>::build_import_queue(&config, client.clone())?;
// FIXME: this shouldn't need a mutable config. https://github.com/paritytech/substrate/issues/1134
let queue = components::FullComponents::<F>::build_import_queue(&mut config, client.clone())?;
queue.start(DummyLink)?;
let (exit_send, exit_recv) = std::sync::mpsc::channel();
+5 -5
View File
@@ -266,7 +266,7 @@ pub trait ServiceFactory: 'static + Sized {
/// ImportQueue for a full client
fn build_full_import_queue(
config: &FactoryFullConfiguration<Self>,
config: &mut FactoryFullConfiguration<Self>,
_client: Arc<FullClient<Self>>
) -> Result<Self::FullImportQueue, error::Error> {
if let Some(name) = config.chain_spec.consensus_engine() {
@@ -281,7 +281,7 @@ pub trait ServiceFactory: 'static + Sized {
/// ImportQueue for a light client
fn build_light_import_queue(
config: &FactoryFullConfiguration<Self>,
config: &mut FactoryFullConfiguration<Self>,
_client: Arc<LightClient<Self>>
) -> Result<Self::LightImportQueue, error::Error> {
if let Some(name) = config.chain_spec.consensus_engine() {
@@ -336,7 +336,7 @@ pub trait Components: Sized + 'static {
/// instance of import queue for clients
fn build_import_queue(
config: &FactoryFullConfiguration<Self::Factory>,
config: &mut FactoryFullConfiguration<Self::Factory>,
client: Arc<ComponentClient<Self>>
) -> Result<Self::ImportQueue, error::Error>;
}
@@ -409,7 +409,7 @@ impl<Factory: ServiceFactory> Components for FullComponents<Factory> {
}
fn build_import_queue(
config: &FactoryFullConfiguration<Self::Factory>,
config: &mut FactoryFullConfiguration<Self::Factory>,
client: Arc<ComponentClient<Self>>
) -> Result<Self::ImportQueue, error::Error> {
Factory::build_full_import_queue(config, client)
@@ -485,7 +485,7 @@ impl<Factory: ServiceFactory> Components for LightComponents<Factory> {
}
fn build_import_queue(
config: &FactoryFullConfiguration<Self::Factory>,
config: &mut FactoryFullConfiguration<Self::Factory>,
client: Arc<ComponentClient<Self>>
) -> Result<Self::ImportQueue, error::Error> {
Factory::build_light_import_queue(config, client)
+58 -17
View File
@@ -103,6 +103,8 @@ pub struct Service<Components: components::Components> {
keystore: Keystore,
exit: ::exit_future::Exit,
signal: Option<Signal>,
/// Configuration of this Service
pub config: FactoryFullConfiguration<Components::Factory>,
proposer: Arc<ProposerFactory<ComponentClient<Components>, Components::TransactionPoolApi>>,
_rpc_http: Option<rpc::HttpServer>,
_rpc_ws: Option<Mutex<rpc::WsServer>>, // WsServer is not `Sync`, but the service needs to be.
@@ -129,7 +131,7 @@ impl<Components> Service<Components>
{
/// Creates a new service.
pub fn new(
config: FactoryFullConfiguration<Components::Factory>,
mut config: FactoryFullConfiguration<Components::Factory>,
task_executor: TaskExecutor,
)
-> Result<Self, error::Error>
@@ -159,7 +161,7 @@ impl<Components> Service<Components>
};
let (client, on_demand) = Components::build_client(&config, executor)?;
let import_queue = Components::build_import_queue(&config, client.clone())?;
let import_queue = Arc::new(Components::build_import_queue(&mut config, client.clone())?);
let best_header = client.best_block_header()?;
let version = config.full_version();
@@ -168,7 +170,7 @@ impl<Components> Service<Components>
let network_protocol = <Components::Factory>::build_network_protocol(&config)?;
let transaction_pool = Arc::new(
Components::build_transaction_pool(config.transaction_pool, client.clone())?
Components::build_transaction_pool(config.transaction_pool.clone(), client.clone())?
);
let transaction_pool_adapter = TransactionPoolAdapter::<Components> {
imports_external_transactions: !(config.roles == Roles::LIGHT),
@@ -177,19 +179,30 @@ impl<Components> Service<Components>
};
let network_params = Components::CreateNetworkParams::create_network_params(
client.clone(), config.roles, config.network, on_demand.clone(),
transaction_pool_adapter, network_protocol
client.clone(),
config.roles,
config.network.clone(),
on_demand.clone(),
transaction_pool_adapter,
network_protocol,
);
let mut protocol_id = network::ProtocolId::default();
let protocol_id_full = config.chain_spec.protocol_id().unwrap_or(DEFAULT_PROTOCOL_ID).as_bytes();
if protocol_id_full.len() > protocol_id.len() {
warn!("Protocol ID truncated to {} chars", protocol_id.len());
}
let id_len = protocol_id_full.len().min(protocol_id.len());
&mut protocol_id[0..id_len].copy_from_slice(&protocol_id_full[0..id_len]);
let protocol_id = {
let protocol_id_full = config.chain_spec.protocol_id().unwrap_or(DEFAULT_PROTOCOL_ID).as_bytes();
let mut protocol_id = network::ProtocolId::default();
if protocol_id_full.len() > protocol_id.len() {
warn!("Protocol ID truncated to {} chars", protocol_id.len());
}
let id_len = protocol_id_full.len().min(protocol_id.len());
&mut protocol_id[0..id_len].copy_from_slice(&protocol_id_full[0..id_len]);
protocol_id
};
let network = network::Service::new(network_params, protocol_id, import_queue)?;
let network = network::Service::new(
network_params,
protocol_id,
import_queue
)?;
on_demand.map(|on_demand| on_demand.set_service_link(Arc::downgrade(&network)));
{
@@ -244,7 +257,7 @@ impl<Components> Service<Components>
});
// Telemetry
let telemetry = match config.telemetry_url {
let telemetry = match config.telemetry_url.clone() {
Some(url) => {
let is_authority = config.roles == Roles::AUTHORITY;
let pubkey = format!("{}", public_key);
@@ -276,6 +289,7 @@ impl<Components> Service<Components>
transaction_pool: transaction_pool,
signal: Some(signal),
keystore: keystore,
config,
proposer,
exit,
_rpc_http: rpc_http,
@@ -283,6 +297,23 @@ impl<Components> Service<Components>
_telemetry: telemetry,
})
}
/// give the authority key, if we are an authority and have a key
pub fn authority_key(&self) -> Option<primitives::ed25519::Pair> {
if self.config.roles != Roles::AUTHORITY { return None }
let keystore = &self.keystore;
if let Ok(Some(Ok(key))) = keystore.contents().map(|keys| keys.get(0)
.map(|k| keystore.load(k, "")))
{
Some(key)
} else {
None
}
}
pub fn config(&self) -> &FactoryFullConfiguration<Components::Factory> {
&self.config
}
}
impl<Components> Service<Components> where Components: components::Components {
@@ -466,6 +497,9 @@ impl<C: Components> network::TransactionPool<ComponentExHash<C>, ComponentBlock<
/// Configuration = (),
/// FullService = Service<FullComponents<Self>>
/// { |config, executor| Service::<FullComponents<Factory>>::new(config, executor) },
/// // Setup as Consensus Authority (if the role and key are given)
/// AuthoritySetup = {
/// |service: Self::FullService, executor: TaskExecutor, key: Arc<Pair>| { Ok(service) }},
/// LightService = Service<LightComponents<Self>>
/// { |config, executor| Service::<LightComponents<Factory>>::new(config, executor) },
/// // Declare the import queue. The import queue is special as it takes two initializers.
@@ -491,6 +525,7 @@ macro_rules! construct_service_factory {
Genesis = $genesis:ty,
Configuration = $config:ty,
FullService = $full_service:ty { $( $full_service_init:tt )* },
AuthoritySetup = { $( $authority_setup:tt )* },
LightService = $light_service:ty { $( $light_service_init:tt )* },
FullImportQueue = $full_import_queue:ty
{ $( $full_import_queue_init:tt )* },
@@ -539,14 +574,14 @@ macro_rules! construct_service_factory {
}
fn build_full_import_queue(
config: &$crate::FactoryFullConfiguration<Self>,
config: &mut $crate::FactoryFullConfiguration<Self>,
client: $crate::Arc<$crate::FullClient<Self>>,
) -> $crate::Result<Self::FullImportQueue, $crate::Error> {
( $( $full_import_queue_init )* ) (config, client)
}
fn build_light_import_queue(
config: &FactoryFullConfiguration<Self>,
config: &mut FactoryFullConfiguration<Self>,
client: Arc<$crate::LightClient<Self>>,
) -> Result<Self::LightImportQueue, $crate::Error> {
( $( $light_import_queue_init )* ) (config, client)
@@ -565,7 +600,13 @@ macro_rules! construct_service_factory {
executor: $crate::TaskExecutor
) -> Result<Self::FullService, $crate::Error>
{
( $( $full_service_init )* ) (config, executor)
( $( $full_service_init )* ) (config, executor.clone()).and_then(|service| {
if let Some(key) = (&service).authority_key() {
($( $authority_setup )*)(service, executor, Arc::new(key))
} else {
Ok(service)
}
})
}
}
}