mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-01 14:47:55 +00:00
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:
@@ -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"
|
||||
@@ -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>
|
||||
@@ -0,0 +1,3 @@
|
||||
# Template Node
|
||||
|
||||
A new SRML-based Substrate node, ready for hacking.
|
||||
@@ -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");
|
||||
}
|
||||
Executable
+26
@@ -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
|
||||
Executable
+16
@@ -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",
|
||||
]
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
+2079
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
@@ -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::*;
|
||||
@@ -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,
|
||||
}),
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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"];
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
@@ -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)
|
||||
},
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user