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
+39
View File
@@ -0,0 +1,39 @@
[package]
name = "node-template"
version = "0.9.0"
authors = ["Parity Technologies <admin@parity.io>"]
build = "build.rs"
edition = "2018"
[[bin]]
name = "template-node"
path = "src/main.rs"
[dependencies]
error-chain = "0.12"
futures = "0.1"
ctrlc = { version = "3.0", features = ["termination"] }
log = "0.4"
tokio = "0.1"
exit-future = "0.1"
parking_lot = "0.4"
hex-literal = "0.1"
slog = "^2"
parity-codec = "3.0"
trie-root = "0.9"
sr-io = { path = "../core/sr-io" }
substrate-cli = { path = "../core/cli" }
primitives = { package = "substrate-primitives", path = "../core/primitives" }
substrate-executor = { path = "../core/executor" }
substrate-service = { path = "../core/service" }
inherents = { package = "substrate-inherents", path = "../core/inherents" }
transaction-pool = { package = "substrate-transaction-pool", path = "../core/transaction-pool" }
substrate-network = { path = "../core/network" }
consensus = { package = "substrate-consensus-aura", path = "../core/consensus/aura" }
substrate-client = { path = "../core/client" }
basic-authorship = { package = "substrate-basic-authorship", path = "../core/basic-authorship" }
node-template-runtime = { path = "runtime" }
node-executor = { path = "../node/executor" }
[build-dependencies]
vergen = "3"
+24
View File
@@ -0,0 +1,24 @@
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org>
+3
View File
@@ -0,0 +1,3 @@
# Template Node
A new SRML-based Substrate node, ready for hacking.
+8
View File
@@ -0,0 +1,8 @@
use vergen::{ConstantsFlags, generate_cargo_keys};
const ERROR_MSG: &'static str = "Failed to generate metadata files";
fn main() {
generate_cargo_keys(ConstantsFlags::all()).expect(ERROR_MSG);
println!("cargo:rerun-if-changed=.git/HEAD");
}
+26
View File
@@ -0,0 +1,26 @@
#!/usr/bin/env bash
set -e
PROJECT_ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
export CARGO_INCREMENTAL=0
bold=$(tput bold)
normal=$(tput sgr0)
# Save current directory.
pushd . >/dev/null
for SRC in runtime/wasm
do
echo "${bold}Building webassembly binary in $SRC...${normal}"
cd "$PROJECT_ROOT/$SRC"
./build.sh
cd - >> /dev/null
done
# Restore initial directory.
popd >/dev/null
+16
View File
@@ -0,0 +1,16 @@
#!/usr/bin/env bash
set -e
echo "*** Initialising WASM build environment"
if [ -z $CI_PROJECT_NAME ] ; then
rustup update nightly
rustup update stable
fi
rustup target add wasm32-unknown-unknown --toolchain nightly
# Install wasm-gc. It's useful for stripping slimming down wasm binaries.
command -v wasm-gc || \
cargo +nightly install --git https://github.com/alexcrichton/wasm-gc --force
@@ -0,0 +1,53 @@
[package]
name = "node-template-runtime"
version = "0.9.0"
authors = ["Parity Technologies <admin@parity.io>"]
edition = "2018"
[dependencies]
serde = { version = "1.0", default-features = false }
serde_derive = { version = "1.0", optional = true }
safe-mix = { version = "1.0", default-features = false }
parity-codec = { version = "3.0", default-features = false }
parity-codec-derive = { version = "3.0", default-features = false }
rstd = { package = "sr-std", path = "../../core/sr-std", default_features = false }
runtime-io = { package = "sr-io", path = "../../core/sr-io", default_features = false }
version = { package = "sr-version", path = "../../core/sr-version", default_features = false }
support = { package = "srml-support", path = "../../srml/support", default_features = false }
primitives = { package = "substrate-primitives", path = "../../core/primitives", default_features = false }
balances = { package = "srml-balances", path = "../../srml/balances", default_features = false }
consensus = { package = "srml-consensus", path = "../../srml/consensus", default_features = false }
aura = { package = "srml-aura", path = "../../srml/aura", default_features = false }
executive = { package = "srml-executive", path = "../../srml/executive", default_features = false }
indices = { package = "srml-indices", path = "../../srml/indices", default_features = false }
system = { package = "srml-system", path = "../../srml/system", default_features = false }
timestamp = { package = "srml-timestamp", path = "../../srml/timestamp", default_features = false }
sudo = { package = "srml-sudo", path = "../../srml/sudo", default_features = false }
runtime-primitives = { package = "sr-primitives", path = "../../core/sr-primitives", default_features = false }
substrate-client = { path = "../../core/client", default_features = false }
consensus-aura = { package = "substrate-consensus-aura-primitives", path = "../../core/consensus/aura/primitives", default_features = false }
[features]
default = ["std"]
std = [
"parity-codec/std",
"parity-codec-derive/std",
"primitives/std",
"substrate-client/std",
"rstd/std",
"runtime-io/std",
"support/std",
"balances/std",
"executive/std",
"aura/std",
"indices/std",
"primitives/std",
"system/std",
"timestamp/std",
"sudo/std",
"version/std",
"serde_derive",
"serde/std",
"safe-mix/std",
"consensus-aura/std",
]
+268
View File
@@ -0,0 +1,268 @@
//! The Substrate Node Template runtime. This can be compiled with `#[no_std]`, ready for Wasm.
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(not(feature = "std"), feature(alloc))]
// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256.
#![recursion_limit="256"]
#[cfg(feature = "std")]
#[macro_use]
extern crate serde_derive;
use substrate_client as client;
#[macro_use]
extern crate parity_codec_derive;
use rstd::prelude::*;
#[cfg(feature = "std")]
use primitives::bytes;
use primitives::{Ed25519AuthorityId, OpaqueMetadata};
use runtime_primitives::{
ApplyResult, transaction_validity::TransactionValidity, Ed25519Signature, generic,
traits::{self, BlakeTwo256, Block as BlockT, StaticLookup}, create_runtime_str
};
use client::{
block_builder::api::{CheckInherentsResult, InherentData, self as block_builder_api},
runtime_api, impl_runtime_apis
};
use version::RuntimeVersion;
#[cfg(feature = "std")]
use version::NativeVersion;
// A few exports that help ease life for downstream crates.
#[cfg(any(feature = "std", test))]
pub use runtime_primitives::BuildStorage;
pub use consensus::Call as ConsensusCall;
pub use timestamp::Call as TimestampCall;
pub use balances::Call as BalancesCall;
pub use runtime_primitives::{Permill, Perbill};
pub use timestamp::BlockPeriod;
pub use support::{StorageValue, construct_runtime};
/// Alias to Ed25519 pubkey that identifies an account on the chain.
pub type AccountId = primitives::H256;
/// A hash of some data used by the chain.
pub type Hash = primitives::H256;
/// Index of a block number in the chain.
pub type BlockNumber = u64;
/// Index of an account's extrinsic in the chain.
pub type Nonce = u64;
/// Opaque types. These are used by the CLI to instantiate machinery that don't need to know
/// the specifics of the runtime. They can then be made to be agnostic over specific formats
/// of data like extrinsics, allowing for them to continue syncing the network through upgrades
/// to even the core datastructures.
pub mod opaque {
use super::*;
/// Opaque, encoded, unchecked extrinsic.
#[derive(PartialEq, Eq, Clone, Default, Encode, Decode)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
pub struct UncheckedExtrinsic(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>);
impl traits::Extrinsic for UncheckedExtrinsic {
fn is_signed(&self) -> Option<bool> {
None
}
}
/// Opaque block header type.
pub type Header = generic::Header<BlockNumber, BlakeTwo256, generic::DigestItem<Hash, Ed25519AuthorityId>>;
/// Opaque block type.
pub type Block = generic::Block<Header, UncheckedExtrinsic>;
/// Opaque block identifier type.
pub type BlockId = generic::BlockId<Block>;
/// Opaque session key type.
pub type SessionKey = Ed25519AuthorityId;
}
/// This runtime version.
pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: create_runtime_str!("template-node"),
impl_name: create_runtime_str!("template-node"),
authoring_version: 3,
spec_version: 3,
impl_version: 0,
apis: RUNTIME_API_VERSIONS,
};
/// The version infromation used to identify this runtime when compiled natively.
#[cfg(feature = "std")]
pub fn native_version() -> NativeVersion {
NativeVersion {
runtime_version: VERSION,
can_author_with: Default::default(),
}
}
impl system::Trait for Runtime {
/// The identifier used to distinguish between accounts.
type AccountId = AccountId;
/// The lookup mechanism to get account ID from whatever is passed in dispatchers.
type Lookup = Indices;
/// The index type for storing how many extrinsics an account has signed.
type Index = Nonce;
/// The index type for blocks.
type BlockNumber = BlockNumber;
/// The type for hashing blocks and tries.
type Hash = Hash;
/// The hashing algorithm used.
type Hashing = BlakeTwo256;
/// The header digest type.
type Digest = generic::Digest<Log>;
/// The header type.
type Header = generic::Header<BlockNumber, BlakeTwo256, Log>;
/// The ubiquitous event type.
type Event = Event;
/// The ubiquitous log type.
type Log = Log;
/// The ubiquitous origin type.
type Origin = Origin;
}
impl aura::Trait for Runtime {
type HandleReport = ();
}
impl consensus::Trait for Runtime {
/// The identifier we use to refer to authorities.
type SessionKey = Ed25519AuthorityId;
// The aura module handles offline-reports internally
// rather than using an explicit report system.
type InherentOfflineReport = ();
/// The ubiquitous log type.
type Log = Log;
}
impl indices::Trait for Runtime {
/// The type for recording indexing into the account enumeration. If this ever overflows, there
/// will be problems!
type AccountIndex = u32;
/// Use the standard means of resolving an index hint from an id.
type ResolveHint = indices::SimpleResolveHint<Self::AccountId, Self::AccountIndex>;
/// Determine whether an account is dead.
type IsDeadAccount = Balances;
/// The uniquitous event type.
type Event = Event;
}
impl timestamp::Trait for Runtime {
/// A timestamp: seconds since the unix epoch.
type Moment = u64;
type OnTimestampSet = Aura;
}
impl balances::Trait for Runtime {
/// The type for recording an account's balance.
type Balance = u128;
/// What to do if an account's free balance gets zeroed.
type OnFreeBalanceZero = ();
/// What to do if a new account is created.
type OnNewAccount = Indices;
/// Restrict whether an account can transfer funds. We don't place any further restrictions.
type EnsureAccountLiquid = ();
/// The uniquitous event type.
type Event = Event;
}
impl sudo::Trait for Runtime {
/// The uniquitous event type.
type Event = Event;
type Proposal = Call;
}
construct_runtime!(
pub enum Runtime with Log(InternalLog: DigestItem<Hash, Ed25519AuthorityId>) where
Block = Block,
NodeBlock = opaque::Block,
UncheckedExtrinsic = UncheckedExtrinsic
{
System: system::{default, Log(ChangesTrieRoot)},
Timestamp: timestamp::{Module, Call, Storage, Config<T>, Inherent},
Consensus: consensus::{Module, Call, Storage, Config<T>, Log(AuthoritiesChange), Inherent},
Aura: aura::{Module},
Indices: indices,
Balances: balances,
Sudo: sudo,
}
);
/// The type used as a helper for interpreting the sender of transactions.
type Context = system::ChainContext<Runtime>;
/// The address format for describing accounts.
type Address = <Indices as StaticLookup>::Source;
/// Block header type as expected by this runtime.
pub type Header = generic::Header<BlockNumber, BlakeTwo256, Log>;
/// Block type as expected by this runtime.
pub type Block = generic::Block<Header, UncheckedExtrinsic>;
/// BlockId type as expected by this runtime.
pub type BlockId = generic::BlockId<Block>;
/// Unchecked extrinsic type as expected by this runtime.
pub type UncheckedExtrinsic = generic::UncheckedMortalCompactExtrinsic<Address, Nonce, Call, Ed25519Signature>;
/// Extrinsic type that has already been checked.
pub type CheckedExtrinsic = generic::CheckedExtrinsic<AccountId, Nonce, Call>;
/// Executive: handles dispatch to the various modules.
pub type Executive = executive::Executive<Runtime, Block, Context, Balances, AllModules>;
// Implement our runtime API endpoints. This is just a bunch of proxying.
impl_runtime_apis! {
impl runtime_api::Core<Block> for Runtime {
fn version() -> RuntimeVersion {
VERSION
}
fn authorities() -> Vec<Ed25519AuthorityId> {
Consensus::authorities()
}
fn execute_block(block: Block) {
Executive::execute_block(block)
}
fn initialise_block(header: &<Block as BlockT>::Header) {
Executive::initialise_block(header)
}
}
impl runtime_api::Metadata<Block> for Runtime {
fn metadata() -> OpaqueMetadata {
Runtime::metadata().into()
}
}
impl block_builder_api::BlockBuilder<Block> for Runtime {
fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyResult {
Executive::apply_extrinsic(extrinsic)
}
fn finalise_block() -> <Block as BlockT>::Header {
Executive::finalise_block()
}
fn inherent_extrinsics(data: InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
data.create_extrinsics()
}
fn check_inherents(block: Block, data: InherentData) -> CheckInherentsResult {
data.check_extrinsics(&block)
}
fn random_seed() -> <Block as BlockT>::Hash {
System::random_seed()
}
}
impl runtime_api::TaggedTransactionQueue<Block> for Runtime {
fn validate_transaction(tx: <Block as BlockT>::Extrinsic) -> TransactionValidity {
Executive::validate_transaction(tx)
}
}
impl consensus_aura::AuraApi<Block> for Runtime {
fn slot_duration() -> u64 {
Aura::slot_duration()
}
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,24 @@
[package]
name = "node-template-runtime-wasm"
version = "0.9.0"
authors = ["Parity Technologies <admin@parity.io>"]
edition = "2018"
[lib]
crate-type = ["cdylib"]
[dependencies]
node-template-runtime = { path = "..", default-features = false }
[features]
default = []
std = [
"node-template-runtime/std",
]
[profile.release]
panic = "abort"
lto = true
[workspace]
members = []
+13
View File
@@ -0,0 +1,13 @@
#!/usr/bin/env bash
set -e
if cargo --version | grep -q "nightly"; then
CARGO_CMD="cargo"
else
CARGO_CMD="cargo +nightly"
fi
$CARGO_CMD build --target=wasm32-unknown-unknown --release
for i in node_template_runtime_wasm
do
wasm-gc target/wasm32-unknown-unknown/release/$i.wasm target/wasm32-unknown-unknown/release/$i.compact.wasm
done
@@ -0,0 +1,5 @@
//! The Substrate node template runtime reexported for WebAssembly compile.
#![cfg_attr(not(feature = "std"), no_std)]
pub use node_template_runtime::*;
+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)
},
}
}