Moves node-template into substrate repo (#1637)

* Make runtime macros work without required `macro_use`

* Adds node-template

* Adds node-template-release tool

* Fixes building `node-template` and improve the release

* Add `profile.release` by release script to remove warning

* Adds script for releasing the node template

* Fixes compilation after master merge

* Port node-template to edition 2018

* Remove license

* Fixes compilation after master merge

* Add `node-template-release.sh` into the CI

* WIP Ci integrate node template (#1701)

* copy artifacts to s3 bucket latest path

* typo

* bucket name

* Update wasm files
This commit is contained in:
Bastian Köcher
2019-02-06 17:15:12 +01:00
committed by GitHub
parent b6fd967dfb
commit 567122fab5
38 changed files with 3362 additions and 223 deletions
+104
View File
@@ -0,0 +1,104 @@
use primitives::{Ed25519AuthorityId, ed25519};
use node_template_runtime::{
AccountId, GenesisConfig, ConsensusConfig, TimestampConfig, BalancesConfig,
SudoConfig, IndicesConfig
};
use substrate_service;
// Note this is the URL for the telemetry server
//const STAGING_TELEMETRY_URL: &str = "wss://telemetry.polkadot.io/submit/";
/// Specialised `ChainSpec`. This is a specialisation of the general Substrate ChainSpec type.
pub type ChainSpec = substrate_service::ChainSpec<GenesisConfig>;
/// The chain specification option. This is expected to come in from the CLI and
/// is little more than one of a number of alternatives which can easily be converted
/// from a string (`--chain=...`) into a `ChainSpec`.
#[derive(Clone, Debug)]
pub enum Alternative {
/// Whatever the current runtime is, with just Alice as an auth.
Development,
/// Whatever the current runtime is, with simple Alice/Bob auths.
LocalTestnet,
}
impl Alternative {
/// Get an actual chain config from one of the alternatives.
pub(crate) fn load(self) -> Result<ChainSpec, String> {
Ok(match self {
Alternative::Development => ChainSpec::from_genesis(
"Development",
"dev",
|| testnet_genesis(vec![
ed25519::Pair::from_seed(b"Alice ").public().into(),
], vec![
ed25519::Pair::from_seed(b"Alice ").public().0.into(),
],
ed25519::Pair::from_seed(b"Alice ").public().0.into()
),
vec![],
None,
None,
None,
None
),
Alternative::LocalTestnet => ChainSpec::from_genesis(
"Local Testnet",
"local_testnet",
|| testnet_genesis(vec![
ed25519::Pair::from_seed(b"Alice ").public().into(),
ed25519::Pair::from_seed(b"Bob ").public().into(),
], vec![
ed25519::Pair::from_seed(b"Alice ").public().0.into(),
ed25519::Pair::from_seed(b"Bob ").public().0.into(),
ed25519::Pair::from_seed(b"Charlie ").public().0.into(),
ed25519::Pair::from_seed(b"Dave ").public().0.into(),
ed25519::Pair::from_seed(b"Eve ").public().0.into(),
ed25519::Pair::from_seed(b"Ferdie ").public().0.into(),
],
ed25519::Pair::from_seed(b"Alice ").public().0.into()
),
vec![],
None,
None,
None,
None
),
})
}
pub(crate) fn from(s: &str) -> Option<Self> {
match s {
"dev" => Some(Alternative::Development),
"" | "local" => Some(Alternative::LocalTestnet),
_ => None,
}
}
}
fn testnet_genesis(initial_authorities: Vec<Ed25519AuthorityId>, endowed_accounts: Vec<AccountId>, root_key: AccountId) -> GenesisConfig {
GenesisConfig {
consensus: Some(ConsensusConfig {
code: include_bytes!("../runtime/wasm/target/wasm32-unknown-unknown/release/node_template_runtime_wasm.compact.wasm").to_vec(),
authorities: initial_authorities.clone(),
}),
system: None,
timestamp: Some(TimestampConfig {
period: 5, // 5 second block time.
}),
indices: Some(IndicesConfig {
ids: endowed_accounts.clone(),
}),
balances: Some(BalancesConfig {
transaction_base_fee: 1,
transaction_byte_fee: 0,
existential_deposit: 500,
transfer_fee: 0,
creation_fee: 0,
balances: endowed_accounts.iter().map(|&k|(k, (1 << 60))).collect(),
}),
sudo: Some(SudoConfig {
key: root_key,
}),
}
}
+88
View File
@@ -0,0 +1,88 @@
use crate::service;
use futures::{future, Future, sync::oneshot};
use std::cell::RefCell;
use tokio::runtime::Runtime;
pub use substrate_cli::{VersionInfo, IntoExit, error};
use substrate_cli::{informant, parse_and_execute, NoCustom};
use substrate_service::{ServiceFactory, Roles as ServiceRoles};
use crate::chain_spec;
use std::ops::Deref;
/// Parse command line arguments into service configuration.
pub fn run<I, T, E>(args: I, exit: E, version: VersionInfo) -> error::Result<()> where
I: IntoIterator<Item = T>,
T: Into<std::ffi::OsString> + Clone,
E: IntoExit,
{
parse_and_execute::<service::Factory, NoCustom, NoCustom, _, _, _, _, _>(
load_spec, &version, "substrate-node", args, exit,
|exit, _custom_args, config| {
info!("{}", version.name);
info!(" version {}", config.full_version());
info!(" by {}, 2017, 2018", version.author);
info!("Chain specification: {}", config.chain_spec.name());
info!("Node name: {}", config.name);
info!("Roles: {:?}", config.roles);
let runtime = Runtime::new().map_err(|e| format!("{:?}", e))?;
let executor = runtime.executor();
match config.roles {
ServiceRoles::LIGHT => run_until_exit(
runtime,
service::Factory::new_light(config, executor).map_err(|e| format!("{:?}", e))?,
exit
),
_ => run_until_exit(
runtime,
service::Factory::new_full(config, executor).map_err(|e| format!("{:?}", e))?,
exit
),
}.map_err(|e| format!("{:?}", e))
}
).map_err(Into::into).map(|_| ())
}
fn load_spec(id: &str) -> Result<Option<chain_spec::ChainSpec>, String> {
Ok(match chain_spec::Alternative::from(id) {
Some(spec) => Some(spec.load()?),
None => None,
})
}
fn run_until_exit<T, C, E>(
mut runtime: Runtime,
service: T,
e: E,
) -> error::Result<()>
where
T: Deref<Target=substrate_service::Service<C>>,
C: substrate_service::Components,
E: IntoExit,
{
let (exit_send, exit) = exit_future::signal();
let executor = runtime.executor();
informant::start(&service, exit.clone(), executor.clone());
let _ = runtime.block_on(e.into_exit());
exit_send.fire();
Ok(())
}
// handles ctrl-c
pub struct Exit;
impl IntoExit for Exit {
type Exit = future::MapErr<oneshot::Receiver<()>, fn(oneshot::Canceled) -> ()>;
fn into_exit(self) -> Self::Exit {
// can't use signal directly here because CtrlC takes only `Fn`.
let (exit_send, exit) = oneshot::channel();
let exit_send_cell = RefCell::new(Some(exit_send));
ctrlc::set_handler(move || {
if let Some(exit_send) = exit_send_cell.try_borrow_mut().expect("signal handler not reentrant; qed").take() {
exit_send.send(()).expect("Error sending exit notification");
}
}).expect("Error setting Ctrl-C handler");
exit.map_err(drop)
}
}
+13
View File
@@ -0,0 +1,13 @@
//! Initialization errors.
use client;
error_chain! {
foreign_links {
Io(::std::io::Error) #[doc="IO error"];
Cli(::clap::Error) #[doc="CLI error"];
}
links {
Client(client::error::Error, client::error::ErrorKind) #[doc="Client error"];
}
}
+36
View File
@@ -0,0 +1,36 @@
//! Substrate Node Template CLI library.
#![warn(missing_docs)]
#![warn(unused_extern_crates)]
#[macro_use]
extern crate error_chain;
#[macro_use]
extern crate log;
#[macro_use]
extern crate substrate_network as network;
#[macro_use]
extern crate substrate_executor;
#[macro_use]
extern crate substrate_service;
mod chain_spec;
mod service;
mod cli;
pub use substrate_cli::{VersionInfo, IntoExit, error};
fn run() -> cli::error::Result<()> {
let version = VersionInfo {
name: "Substrate Node",
commit: env!("VERGEN_SHA_SHORT"),
version: env!("CARGO_PKG_VERSION"),
executable_name: "template-node",
author: "Anonymous",
description: "Template Node",
support_url: "support.anonymous.an",
};
cli::run(::std::env::args(), cli::Exit, version)
}
quick_main!(run);
+112
View File
@@ -0,0 +1,112 @@
//! Service and ServiceFactory implementation. Specialized wrapper over Substrate service.
#![warn(unused_extern_crates)]
use std::sync::Arc;
use transaction_pool::{self, txpool::{Pool as TransactionPool}};
use node_template_runtime::{self, GenesisConfig, opaque::Block, RuntimeApi};
use substrate_service::{
FactoryFullConfiguration, LightComponents, FullComponents, FullBackend,
FullClient, LightClient, LightBackend, FullExecutor, LightExecutor,
TaskExecutor,
};
use basic_authorship::ProposerFactory;
use node_executor;
use consensus::{import_queue, start_aura, AuraImportQueue, SlotDuration, NothingExtra};
use substrate_client as client;
use primitives::ed25519::Pair;
use inherents::InherentDataProviders;
pub use substrate_executor::NativeExecutor;
// Our native executor instance.
native_executor_instance!(
pub Executor,
node_template_runtime::api::dispatch,
node_template_runtime::native_version,
include_bytes!("../runtime/wasm/target/wasm32-unknown-unknown/release/node_template_runtime_wasm.compact.wasm")
);
#[derive(Default)]
pub struct NodeConfig {
inherent_data_providers: InherentDataProviders,
}
construct_simple_protocol! {
/// Demo protocol attachment for substrate.
pub struct NodeProtocol where Block = Block { }
}
construct_service_factory! {
struct Factory {
Block = Block,
RuntimeApi = RuntimeApi,
NetworkProtocol = NodeProtocol { |config| Ok(NodeProtocol::new()) },
RuntimeDispatch = node_executor::Executor,
FullTransactionPoolApi = transaction_pool::ChainApi<client::Client<FullBackend<Self>, FullExecutor<Self>, Block, RuntimeApi>, Block>
{ |config, client| Ok(TransactionPool::new(config, transaction_pool::ChainApi::new(client))) },
LightTransactionPoolApi = transaction_pool::ChainApi<client::Client<LightBackend<Self>, LightExecutor<Self>, Block, RuntimeApi>, Block>
{ |config, client| Ok(TransactionPool::new(config, transaction_pool::ChainApi::new(client))) },
Genesis = GenesisConfig,
Configuration = NodeConfig,
FullService = FullComponents<Self>
{ |config: FactoryFullConfiguration<Self>, executor: TaskExecutor|
FullComponents::<Factory>::new(config, executor)
},
AuthoritySetup = {
|service: Self::FullService, executor: TaskExecutor, key: Option<Arc<Pair>>| {
if let Some(key) = key {
info!("Using authority key {}", key.public());
let proposer = Arc::new(ProposerFactory {
client: service.client(),
transaction_pool: service.transaction_pool(),
});
let client = service.client();
executor.spawn(start_aura(
SlotDuration::get_or_compute(&*client)?,
key.clone(),
client.clone(),
client,
proposer,
service.network(),
service.on_exit(),
service.config.custom.inherent_data_providers.clone(),
)?);
}
Ok(service)
}
},
LightService = LightComponents<Self>
{ |config, executor| <LightComponents<Factory>>::new(config, executor) },
FullImportQueue = AuraImportQueue<
Self::Block,
FullClient<Self>,
NothingExtra,
>
{ |config: &mut FactoryFullConfiguration<Self> , client: Arc<FullClient<Self>>|
import_queue(
SlotDuration::get_or_compute(&*client)?,
client.clone(),
None,
client,
NothingExtra,
config.custom.inherent_data_providers.clone(),
).map_err(Into::into)
},
LightImportQueue = AuraImportQueue<
Self::Block,
LightClient<Self>,
NothingExtra,
>
{ |config: &mut FactoryFullConfiguration<Self>, client: Arc<LightClient<Self>>|
import_queue(
SlotDuration::get_or_compute(&*client)?,
client.clone(),
None,
client,
NothingExtra,
config.custom.inherent_data_providers.clone(),
).map_err(Into::into)
},
}
}