From 927f49e3052895f0dd56cd5bc4b1d8154389a147 Mon Sep 17 00:00:00 2001 From: Crystalin Date: Wed, 6 May 2020 09:10:28 -0400 Subject: [PATCH 1/5] Adds compiled folder to .gitignore --- .gitignore | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 89f5dacebd7be..f4327f5dd0afb 100644 --- a/.gitignore +++ b/.gitignore @@ -5,9 +5,8 @@ book **/.DS_Store # Rust directories -**/node/target +**/target *.lock **/scripts/staging/tmp **/scripts/staging/spec.json **/scripts/staging/rawspec.json - From a3a3d61406c243e782ace45c39b4dcb55ced8ea3 Mon Sep 17 00:00:00 2001 From: Crystalin Date: Wed, 6 May 2020 09:11:06 -0400 Subject: [PATCH 2/5] Adds formatting description (EditorConfig) and autosave formatting --- .editorconfig | 22 ++++++++++++++++++++++ .vscode/settings.json | 3 +++ 2 files changed, 25 insertions(+) create mode 100644 .editorconfig create mode 100644 .vscode/settings.json diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000000..2b40ec32fac3e --- /dev/null +++ b/.editorconfig @@ -0,0 +1,22 @@ +root = true +[*] +indent_style=tab +indent_size=tab +tab_width=4 +end_of_line=lf +charset=utf-8 +trim_trailing_whitespace=true +max_line_length=100 +insert_final_newline=true + +[*.yml] +indent_style=space +indent_size=2 +tab_width=8 +end_of_line=lf + +[*.sh] +indent_style=space +indent_size=2 +tab_width=8 +end_of_line=lf diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000000000..23fd35f0e0e70 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "editor.formatOnSave": true +} \ No newline at end of file From 7998f97f2a00ab5bdbce891223fe2aee592308fb Mon Sep 17 00:00:00 2001 From: Crystalin Date: Wed, 6 May 2020 09:11:54 -0400 Subject: [PATCH 3/5] Removes existing substrate sutrcture --- node/Cargo.toml | 87 ----- node/build.rs | 9 - node/src/chain_spec.rs | 216 ------------ node/src/cli.rs | 11 - node/src/command.rs | 45 --- node/src/main.rs | 25 -- node/src/service.rs | 331 ------------------ pallets/mb-core/Cargo.toml | 35 -- pallets/mb-core/src/lib.rs | 131 ------- pallets/mb-session/Cargo.toml | 40 --- pallets/mb-session/src/lib.rs | 403 --------------------- primitives/Cargo.toml | 21 -- primitives/src/lib.rs | 64 ---- runtime/Cargo.toml | 118 ------- runtime/build.rs | 10 - runtime/src/constants.rs | 75 ---- runtime/src/impls.rs | 174 ---------- runtime/src/lib.rs | 634 ---------------------------------- 18 files changed, 2429 deletions(-) delete mode 100644 node/Cargo.toml delete mode 100644 node/build.rs delete mode 100644 node/src/chain_spec.rs delete mode 100644 node/src/cli.rs delete mode 100644 node/src/command.rs delete mode 100644 node/src/main.rs delete mode 100644 node/src/service.rs delete mode 100644 pallets/mb-core/Cargo.toml delete mode 100644 pallets/mb-core/src/lib.rs delete mode 100644 pallets/mb-session/Cargo.toml delete mode 100644 pallets/mb-session/src/lib.rs delete mode 100644 primitives/Cargo.toml delete mode 100644 primitives/src/lib.rs delete mode 100644 runtime/Cargo.toml delete mode 100644 runtime/build.rs delete mode 100644 runtime/src/constants.rs delete mode 100644 runtime/src/impls.rs delete mode 100644 runtime/src/lib.rs diff --git a/node/Cargo.toml b/node/Cargo.toml deleted file mode 100644 index a63753d663a8e..0000000000000 --- a/node/Cargo.toml +++ /dev/null @@ -1,87 +0,0 @@ -[package] -name = "moonbeam-node" -version = "0.1.0" -authors = ["PureStake"] -edition = "2018" -license = "Unlicense" -build = "build.rs" - -[[bin]] -name = "moonbeam" -path = "src/main.rs" - -[dependencies] -codec = { package = "parity-scale-codec", version = "1.0.6" } -serde = { version = "1.0.102", features = ["derive"] } -futures = { version = "0.3.1", features = ["compat"] } -hex-literal = "0.2.1" -jsonrpc-core = "14.0.3" -log = "0.4.8" -rand = "0.7.2" -structopt = { version = "0.3.8", optional = true } -tracing = "0.1.10" -serde_json = "1.0.41" - -# primitives -grandpa-primitives = { package = "sp-finality-grandpa", git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02' } -sp-core = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02' } -sp-runtime = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02' } -sp-inherents = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02' } -sp-consensus-babe = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02' } -sp-consensus = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02' } -sp-timestamp = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02' } -sp-finality-tracker = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02' } -sp-authority-discovery = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02' } - -# client dependencies -sc-client = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02' } -sc-transaction-pool = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02' } -sp-transaction-pool = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02' } -sc-network = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02' } -sc-consensus-babe = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02' } -grandpa = { package = "sc-finality-grandpa", git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02' } -sc-rpc = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02' } -sc-service = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02' } -sc-executor = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02' } -sc-basic-authorship = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02' } -sc-chain-spec = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02' } -sc-authority-discovery = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02' } -substrate-frame-rpc-system = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02' } -pallet-transaction-payment-rpc = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02' } -sc-consensus-babe-rpc = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02' } -sc-telemetry = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02' } - -# frame dependencies -pallet-indices = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02' } -pallet-contracts = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -pallet-contracts-rpc = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -pallet-timestamp = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -frame-system = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02' } -pallet-balances = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02' } -pallet-transaction-payment = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02' } -frame-support = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -pallet-im-online = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -pallet-authority-discovery = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02' } - -# CLI-specific dependencies -sc-cli = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02' } - -# node-specific dependencies -node-primitives = { version = "2.0.0-dev", path = "../primitives" } -moonbeam-runtime = { version = "0.1.0", path = "../runtime" } - -[dev-dependencies] -sc-keystore = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02' } -sc-consensus-babe = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', features = ["test-helpers"] } -sc-consensus-epochs = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02' } - -[build-dependencies] -vergen = "3.0.4" -build-script-utils = { package = "substrate-build-script-utils", git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02' } -structopt = { version = "0.3.8", optional = true } - -[features] -default = ["cli"] -cli = [ - "structopt", -] \ No newline at end of file diff --git a/node/build.rs b/node/build.rs deleted file mode 100644 index 222cbb409285b..0000000000000 --- a/node/build.rs +++ /dev/null @@ -1,9 +0,0 @@ -use vergen::{ConstantsFlags, generate_cargo_keys}; - -const ERROR_MSG: &str = "Failed to generate metadata files"; - -fn main() { - generate_cargo_keys(ConstantsFlags::SHA_SHORT).expect(ERROR_MSG); - - build_script_utils::rerun_if_git_head_changed(); -} diff --git a/node/src/chain_spec.rs b/node/src/chain_spec.rs deleted file mode 100644 index c5aa94ad2cf2c..0000000000000 --- a/node/src/chain_spec.rs +++ /dev/null @@ -1,216 +0,0 @@ -use serde::{Serialize, Deserialize}; -use serde_json::{json}; - -use sc_service; -use sc_chain_spec::ChainSpecExtension; -use sp_core::{Pair, Public, sr25519}; -use sp_consensus_babe::{AuthorityId as BabeId}; -use grandpa_primitives::{AuthorityId as GrandpaId}; -use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId; -use sp_runtime::{traits::{Verify, IdentifyAccount}}; -use sc_telemetry::TelemetryEndpoints; - -use pallet_im_online::sr25519::{AuthorityId as ImOnlineId}; - -pub use node_primitives::{AccountId, Balance, Signature, Block}; - -use moonbeam_runtime::{ - GenesisConfig, AuthorityDiscoveryConfig, BabeConfig, BalancesConfig, ContractsConfig, - GrandpaConfig, ImOnlineConfig, SessionConfig, SessionKeys, - IndicesConfig, SudoConfig, SystemConfig, WASM_BINARY, MoonbeamCoreConfig, MoonbeamSessionConfig -}; - -use moonbeam_runtime::constants::mb_genesis::*; -use moonbeam_runtime::constants::currency::*; - -type AccountPublic = ::Signer; - -const STAGING_TELEMETRY_URL: &str = "wss://telemetry.polkadot.io/submit/"; - -#[derive(Default, Clone, Serialize, Deserialize, ChainSpecExtension)] -#[serde(rename_all = "camelCase")] -pub struct Extensions { - /// Block numbers with known hashes. - pub fork_blocks: sc_client::ForkBlocks, - /// Known bad block hashes. - pub bad_blocks: sc_client::BadBlocks, -} - -pub type ChainSpec = sc_service::ChainSpec< - GenesisConfig, - Extensions, ->; - -fn session_keys( - grandpa: GrandpaId, - babe: BabeId, - im_online: ImOnlineId, - authority_discovery: AuthorityDiscoveryId, -) -> SessionKeys { - SessionKeys { grandpa, babe, im_online, authority_discovery } -} - -/// Helper function to generate a crypto pair from seed -pub fn get_from_seed(seed: &str) -> ::Public { - TPublic::Pair::from_string(&format!("//{}", seed), None) - .expect("static values are valid; qed") - .public() -} - -/// Helper function to generate an account ID from seed -pub fn get_account_id_from_seed(seed: &str) -> AccountId where - AccountPublic: From<::Public> -{ - AccountPublic::from(get_from_seed::(seed)).into_account() -} - -/// Helper function to generate stash, controller and session key from seed -pub fn get_authority_keys_from_seed(seed: &str) -> ( - AccountId, - AccountId, - GrandpaId, - BabeId, - ImOnlineId, - AuthorityDiscoveryId, -) { - ( - get_account_id_from_seed::(&format!("{}//stash", seed)), - get_account_id_from_seed::(seed), - get_from_seed::(seed), - get_from_seed::(seed), - get_from_seed::(seed), - get_from_seed::(seed), - ) -} - -fn testnet_genesis( - initial_authorities: Vec<(AccountId, AccountId, GrandpaId, BabeId, ImOnlineId, AuthorityDiscoveryId)>, - endowed_accounts: Vec, - root_key: AccountId, - enable_println: bool -) -> GenesisConfig { - - const ENDOWMENT: Balance = 10_000_000 * GLMR; - const STASH: Balance = 100 * GLMR; - - let keys = initial_authorities.iter().map(|x| { - (x.0.clone(), session_keys(x.2.clone(), x.3.clone(), x.4.clone(), x.5.clone())) - }).collect::>(); - - GenesisConfig { - frame_system: Some(SystemConfig { - code: WASM_BINARY.to_vec(), - changes_trie_config: Default::default(), - }), - pallet_balances: Some(BalancesConfig { - balances: endowed_accounts.iter().cloned() - .map(|k| (k, ENDOWMENT)) - .chain(initial_authorities.iter().map(|x| (x.0.clone(), STASH))) - .collect(), - }), - pallet_session: Some(SessionConfig { - keys: keys, - }), - pallet_indices: Some(IndicesConfig { - indices: vec![], - }), - pallet_sudo: Some(SudoConfig { - key: root_key, - }), - pallet_babe: Some(BabeConfig { - authorities: vec![], - }), - pallet_im_online: Some(ImOnlineConfig { - keys: vec![], - }), - pallet_authority_discovery: Some(AuthorityDiscoveryConfig { - keys: vec![], - }), - pallet_grandpa: Some(GrandpaConfig { - authorities: vec![], - }), - pallet_contracts: Some(ContractsConfig { - current_schedule: pallet_contracts::Schedule { - enable_println, // this should only be enabled on development chains - ..Default::default() - }, - gas_price: 1 * MILLIGLMR, - }), - pallet_vesting: Some(Default::default()), - mb_core: Some(MoonbeamCoreConfig { - treasury: TREASURY_FUND, - genesis_accounts: endowed_accounts.clone(), - }), - mb_session: Some(MoonbeamSessionConfig { - treasury: TREASURY_FUND, - session_validators: initial_authorities.iter().map(|x| { - x.0.clone() - }).collect(), - }), - } -} - -fn development_config_genesis() -> GenesisConfig { - - let seeds = vec![ - "Armstrong", - "Aldrin", - "Collins", - "Armstrong//stash", - "Aldrin//stash", - "Collins//stash" - ]; - let mut accounts: Vec = vec![]; - let mut initial_authorities: Vec<( - AccountId, - AccountId, - GrandpaId, - BabeId, - ImOnlineId, - AuthorityDiscoveryId, - )> = vec![]; - - for s in seeds { - accounts.push( get_account_id_from_seed::(&s) ); - if !s.contains("//stash") { - initial_authorities.push( get_authority_keys_from_seed(&s) ); - } - } - - // default accounts with some endorsement - accounts.push( get_account_id_from_seed::("Alice") ); - accounts.push( get_account_id_from_seed::("Bob") ); - accounts.push( get_account_id_from_seed::("Ferdie") ); - - testnet_genesis( - initial_authorities, - accounts, - get_account_id_from_seed::("Alice"), - true, - ) -} - -/// Development config -/// https://crates.parity.io/sc_chain_spec/struct.ChainSpec.html#method.from_genesis -pub fn development_config() -> ChainSpec { - - let properties = json!({ - "tokenSymbol": "GLMR", - "tokenDecimals": 8 - }); - - ChainSpec::from_genesis( - "Development", - "dev", - development_config_genesis, - vec![], - Some(TelemetryEndpoints::new(vec![(STAGING_TELEMETRY_URL.to_string(), 0)])), - None, - Some(properties.as_object().unwrap().clone()), - Default::default(), - ) -} -/// TODO multiple configs using _id -pub fn load_spec(_id: &str) -> Result, String> { - Ok(Some(development_config())) -} \ No newline at end of file diff --git a/node/src/cli.rs b/node/src/cli.rs deleted file mode 100644 index 0091ef7d75912..0000000000000 --- a/node/src/cli.rs +++ /dev/null @@ -1,11 +0,0 @@ -use sc_cli::{RunCmd, Subcommand}; -use structopt::StructOpt; - -#[derive(Debug, StructOpt)] -pub struct Cli { - #[structopt(subcommand)] - pub subcommand: Option, - - #[structopt(flatten)] - pub run: RunCmd, -} diff --git a/node/src/command.rs b/node/src/command.rs deleted file mode 100644 index 598b3345bca40..0000000000000 --- a/node/src/command.rs +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Substrate is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Substrate. If not, see . - -use sc_cli::{VersionInfo, error}; -use crate::service; -use crate::chain_spec; -use crate::cli::Cli; - -/// Parse and run command line arguments -pub fn run(version: VersionInfo) -> error::Result<()> { - let opt = sc_cli::from_args::(&version); - - let config = sc_service::Configuration::new(&version); - - match opt.subcommand { - Some(subcommand) => sc_cli::run_subcommand( - config, - subcommand, - chain_spec::load_spec, - |config: _| Ok(new_full_start!(config).0), - &version, - ), - None => sc_cli::run( - config, - opt.run, - service::new_light, - service::new_full, - chain_spec::load_spec, - &version, - ) - } -} diff --git a/node/src/main.rs b/node/src/main.rs deleted file mode 100644 index cf8bacf8a919c..0000000000000 --- a/node/src/main.rs +++ /dev/null @@ -1,25 +0,0 @@ -//! Substrate Node Template CLI library. -#![warn(missing_docs)] - -mod chain_spec; -#[macro_use] -mod service; -mod cli; -mod command; - -pub use sc_cli::{VersionInfo, error}; - -fn main() -> Result<(), error::Error> { - let version = VersionInfo { - name: "Moonbeam", - commit: env!("VERGEN_SHA_SHORT"), - version: env!("CARGO_PKG_VERSION"), - executable_name: "moonbeam", - author: "PureStake", - description: "Moonbeam core", - support_url: "purestake.io", - copyright_start_year: 2020, - }; - - command::run(version) -} diff --git a/node/src/service.rs b/node/src/service.rs deleted file mode 100644 index 24ddc20cd9701..0000000000000 --- a/node/src/service.rs +++ /dev/null @@ -1,331 +0,0 @@ -use std::sync::Arc; -use std::time::Duration; -use sc_client::LongestChain; -use sc_service::{error::{Error as ServiceError}, AbstractService, config::Configuration, ServiceBuilder}; -use sp_inherents::InherentDataProviders; -use sc_network::{construct_simple_protocol,Event}; -use futures::prelude::*; -use sc_executor::native_executor_instance; -pub use sc_executor::NativeExecutor; -use grandpa::{self, FinalityProofProvider as GrandpaFinalityProofProvider}; -use sc_consensus_babe; -use node_primitives::{AccountId, Block, Index}; - -use moonbeam_runtime::{self, GenesisConfig, RuntimeApi}; - -// Our native executor instance. -native_executor_instance!( - pub Executor, - moonbeam_runtime::api::dispatch, - moonbeam_runtime::native_version, -); - -construct_simple_protocol! { - /// Demo protocol attachment for substrate. - pub struct NodeProtocol where Block = Block { } -} - -/// Starts a `ServiceBuilder` for a full service. -/// -/// Use this macro if you don't actually need the full service, but just the builder in order to -/// be able to perform chain operations. -macro_rules! new_full_start { - ($config:expr) => {{ - - type RpcExtension = jsonrpc_core::IoHandler; - - let mut import_setup = None; - let inherent_data_providers = sp_inherents::InherentDataProviders::new(); - - let builder = sc_service::ServiceBuilder::new_full::< - node_primitives::Block, moonbeam_runtime::RuntimeApi, crate::service::Executor - >($config)? - .with_select_chain(|_config, backend| { - Ok(sc_client::LongestChain::new(backend.clone())) - })? - .with_transaction_pool(|config, client, _fetcher| { - let pool_api = sc_transaction_pool::FullChainApi::new(client.clone()); - Ok(sc_transaction_pool::BasicPool::new(config, std::sync::Arc::new(pool_api))) - })? - .with_import_queue(|_config, client, mut select_chain, _transaction_pool| { - let select_chain = select_chain.take() - .ok_or_else(|| sc_service::Error::SelectChainRequired)?; - - let (grandpa_block_import, grandpa_link) = - grandpa::block_import::<_, _, _, moonbeam_runtime::RuntimeApi, _>( - client.clone(), &*client, select_chain - )?; - - let justification_import = grandpa_block_import.clone(); - - let (block_import, babe_link) = sc_consensus_babe::block_import( - sc_consensus_babe::Config::get_or_compute(&*client)?, - grandpa_block_import, - client.clone(), - client.clone(), - )?; - - let import_queue = sc_consensus_babe::import_queue( - babe_link.clone(), - block_import.clone(), - Some(Box::new(justification_import)), - None, - client.clone(), - client, - inherent_data_providers.clone(), - )?; - - import_setup = Some((block_import, grandpa_link, babe_link)); - Ok(import_queue) - })? - .with_rpc_extensions(|builder| -> Result { - - use pallet_contracts_rpc::{Contracts, ContractsApi}; - use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApi}; - use sc_consensus_babe_rpc::BabeRPCHandler; - - let mut io = jsonrpc_core::IoHandler::default(); - - let babe_link = import_setup.as_ref().map(|s| &s.2) - .expect("BabeLink is present for full services or set up failed; qed."); - - io.extend_with( - ContractsApi::to_delegate(Contracts::new(builder.client().clone())) - ); - - io.extend_with( - TransactionPaymentApi::to_delegate(TransactionPayment::new(builder.client().clone())) - ); - - io.extend_with( - sc_consensus_babe_rpc::BabeApi::to_delegate( - BabeRPCHandler::new( - builder.client().clone(), - sc_consensus_babe::BabeLink::epoch_changes(babe_link).clone(), - builder.keystore(), - sc_consensus_babe::BabeLink::config(babe_link).clone(), - builder.select_chain().cloned() - .expect("SelectChain is present for full services or set up failed; qed.") - ) - ) - ); - - Ok(io) - })?; - - (builder, import_setup, inherent_data_providers) - }} -} - -pub type NodeConfiguration = Configuration; - -/// Builds a new service for a full client. -pub fn new_full(config: NodeConfiguration) - -> Result -{ - let is_authority = config.roles.is_authority(); - let force_authoring = config.force_authoring; - let name = config.name.clone(); - let disable_grandpa = config.disable_grandpa; - let sentry_nodes = config.network.sentry_nodes.clone(); - - // sentry nodes announce themselves as authorities to the network - // and should run the same protocols authorities do, but it should - // never actively participate in any consensus process. - let participates_in_consensus = is_authority && !config.sentry_mode; - - let (builder, mut import_setup, inherent_data_providers) = new_full_start!(config); - - let service = builder.with_network_protocol(|_| Ok(NodeProtocol::new()))? - .with_finality_proof_provider(|client, backend| - Ok(Arc::new(GrandpaFinalityProofProvider::new(backend, client)) as _) - )? - .build()?; - - let (block_import, grandpa_link, babe_link) = - import_setup.take() - .expect("Link Half and Block Import are present for Full Services or setup failed before. qed"); - - if participates_in_consensus { - let proposer = sc_basic_authorship::ProposerFactory { - client: service.client(), - transaction_pool: service.transaction_pool(), - }; - - let client = service.client(); - let select_chain = service.select_chain() - .ok_or(ServiceError::SelectChainRequired)?; - - let can_author_with = - sp_consensus::CanAuthorWithNativeVersion::new(client.executor().clone()); - - let babe_config = sc_consensus_babe::BabeParams { - keystore: service.keystore(), - client, - select_chain, - env: proposer, - block_import, - sync_oracle: service.network(), - inherent_data_providers: inherent_data_providers.clone(), - force_authoring, - babe_link, - can_author_with, - }; - - let babe = sc_consensus_babe::start_babe(babe_config)?; - service.spawn_essential_task("babe-proposer", babe); - - let network = service.network(); - let dht_event_stream = network.event_stream().filter_map(|e| async move { match e { - Event::Dht(e) => Some(e), - _ => None, - }}).boxed(); - let authority_discovery = sc_authority_discovery::AuthorityDiscovery::new( - service.client(), - network, - sentry_nodes, - service.keystore(), - dht_event_stream, - ); - - service.spawn_task("authority-discovery", authority_discovery); - } - - // if the node isn't actively participating in consensus then it doesn't - // need a keystore, regardless of which protocol we use below. - let keystore = if participates_in_consensus { - Some(service.keystore()) - } else { - None - }; - - let grandpa_config = grandpa::Config { - // FIXME #1578 make this available through chainspec - gossip_duration: Duration::from_millis(333), - justification_period: 512, - name: Some(name), - observer_enabled: true, - keystore, - is_authority, - }; - - match (is_authority, disable_grandpa) { - (false, false) => { - // start the lightweight GRANDPA observer - service.spawn_task("grandpa-observer", grandpa::run_grandpa_observer( - grandpa_config, - grandpa_link, - service.network(), - service.on_exit(), - )?); - }, - (true, false) => { - // start the full GRANDPA voter - let voter_config = grandpa::GrandpaParams { - config: grandpa_config, - link: grandpa_link, - network: service.network(), - inherent_data_providers: inherent_data_providers.clone(), - on_exit: service.on_exit(), - telemetry_on_connect: Some(service.telemetry_on_connect_stream()), - voting_rule: grandpa::VotingRulesBuilder::default().build(), - }; - - // the GRANDPA voter task is considered infallible, i.e. - // if it fails we take down the service with it. - service.spawn_essential_task("grandpa", grandpa::run_grandpa_voter(voter_config)?); - }, - (_, true) => { - grandpa::setup_disabled_grandpa( - service.client(), - &inherent_data_providers, - service.network(), - )?; - }, - } - - Ok(service) -} - -/// Builds a new service for a light client. -pub fn new_light(config: NodeConfiguration) - -> Result -{ - type RpcExtension = jsonrpc_core::IoHandler; - let inherent_data_providers = InherentDataProviders::new(); - - let service = ServiceBuilder::new_light::(config)? - .with_select_chain(|_config, backend| { - Ok(LongestChain::new(backend.clone())) - })? - .with_transaction_pool(|config, client, fetcher| { - let fetcher = fetcher - .ok_or_else(|| "Trying to start light transaction pool without active fetcher")?; - - let pool_api = sc_transaction_pool::LightChainApi::new(client.clone(), fetcher.clone()); - let pool = sc_transaction_pool::BasicPool::with_revalidation_type( - config, Arc::new(pool_api), sc_transaction_pool::RevalidationType::Light, - ); - Ok(pool) - })? - .with_import_queue_and_fprb(|_config, client, backend, fetcher, _select_chain, _tx_pool| { - let fetch_checker = fetcher - .map(|fetcher| fetcher.checker().clone()) - .ok_or_else(|| "Trying to start light import queue without active fetch checker")?; - let grandpa_block_import = grandpa::light_block_import::<_, _, _, RuntimeApi>( - client.clone(), backend, &*client.clone(), Arc::new(fetch_checker), - )?; - let finality_proof_import = grandpa_block_import.clone(); - let finality_proof_request_builder = - finality_proof_import.create_finality_proof_request_builder(); - - let (babe_block_import, babe_link) = sc_consensus_babe::block_import( - sc_consensus_babe::Config::get_or_compute(&*client)?, - grandpa_block_import, - client.clone(), - client.clone(), - )?; - - let import_queue = sc_consensus_babe::import_queue( - babe_link, - babe_block_import, - None, - Some(Box::new(finality_proof_import)), - client.clone(), - client, - inherent_data_providers.clone(), - )?; - - Ok((import_queue, finality_proof_request_builder)) - })? - .with_network_protocol(|_| Ok(NodeProtocol::new()))? - .with_finality_proof_provider(|client, backend| - Ok(Arc::new(GrandpaFinalityProofProvider::new(backend, client)) as _) - )? - .with_rpc_extensions(|builder,| -> - Result - { - use substrate_frame_rpc_system::{LightSystem, SystemApi}; - - let fetcher = builder.fetcher() - .ok_or_else(|| "Trying to start node RPC without active fetcher")?; - let remote_blockchain = builder.remote_backend() - .ok_or_else(|| "Trying to start node RPC without active remote blockchain")?; - - let mut io = jsonrpc_core::IoHandler::default(); - io.extend_with( - SystemApi::::to_delegate( - LightSystem::new( - builder.client().clone(), - remote_blockchain, - fetcher, - builder.pool() - ) - ) - ); - Ok(io) - })? - .build()?; - - Ok(service) -} diff --git a/pallets/mb-core/Cargo.toml b/pallets/mb-core/Cargo.toml deleted file mode 100644 index 48f93068a20b5..0000000000000 --- a/pallets/mb-core/Cargo.toml +++ /dev/null @@ -1,35 +0,0 @@ -[package] -authors = ['PureStake'] -edition = '2018' -name = 'mb-core' -version = '0.1.0' - -[dependencies] -codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -safe-mix = { default-features = false, version = '1.0.0' } -serde = { version = "1.0.102", features = ["derive"] } - -# primitives -sp-core = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -sp-io = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -sp-runtime = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -sp-std = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -sp-staking = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } - -# frame dependencies -frame-support = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -system = { package = 'frame-system', git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -pallet-balances = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -pallet-staking = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } - -[features] -default = ['std'] -std = [ - "sp-std/std", - "sp-staking/std", - 'codec/std', - 'frame-support/std', - 'safe-mix/std', - 'system/std', - 'pallet-staking/std', -] diff --git a/pallets/mb-core/src/lib.rs b/pallets/mb-core/src/lib.rs deleted file mode 100644 index 80c8bf16caf0f..0000000000000 --- a/pallets/mb-core/src/lib.rs +++ /dev/null @@ -1,131 +0,0 @@ -#![cfg_attr(not(feature = "std"), no_std)] - -use sp_std::prelude::*; - -use frame_support::{decl_module, decl_storage, decl_event}; -use frame_support::dispatch::{DispatchResult}; -use frame_support::traits::{OnUnbalanced,Currency,LockableCurrency,Imbalance}; -use system::{ensure_root,RawOrigin}; -use sp_runtime::{traits::{EnsureOrigin,CheckedAdd,CheckedSub}}; - -type BalanceOf = - <::Currency as Currency<::AccountId>>::Balance; - -type NegativeImbalanceOf = - <::Currency as Currency<::AccountId>>::NegativeImbalance; - -type PositiveImbalanceOf = - <::Currency as Currency<::AccountId>>::PositiveImbalance; - -pub trait Trait: system::Trait + pallet_balances::Trait { - type Event: From> + Into<::Event>; - type Currency: LockableCurrency; -} - -decl_storage! { - trait Store for Module as MoonbeamModule { - Treasury get(treasury): BalanceOf; - GenesisAccounts get(genesis_accounts): Vec; - } - add_extra_genesis { - config(treasury): BalanceOf; - config(genesis_accounts): Vec; - build(|config: &GenesisConfig| { - >::put(config.treasury); - let _ = >::append(config.genesis_accounts.clone()); - }); - } -} - -decl_event!( - pub enum Event - where - AccountId = ::AccountId, - BalanceOf = BalanceOf, - { - Absorbed(BalanceOf, BalanceOf), - Rewarded(BalanceOf, BalanceOf), - TreasuryTransferOk(AccountId, BalanceOf, BalanceOf), - } -); - -decl_module! { - pub struct Module for enum Call where origin: T::Origin { - - fn deposit_event() = default; - - // TODO work in progress mint from pot - fn mint( - origin, _to: T::AccountId, _ammount: BalanceOf - ) -> DispatchResult { - let _caller = ensure_root(origin); - Ok(()) - } - - } -} - -pub struct Collective(AccountId); -impl< - O: Into, O>> + From>, - AccountId -> EnsureOrigin for Collective { - type Success = (); - fn try_origin(_o: O) -> Result { - Ok(()) - } -} - -// https://substrate.dev/rustdocs/pre-v2.0-3e65111/pallet_staking/trait.Trait.html#associatedtype.RewardRemainder -pub struct RewardRemainder(T); -impl OnUnbalanced> for RewardRemainder -{ - fn on_nonzero_unbalanced(_amount: NegativeImbalanceOf) { - // TODO Tokens have been minted and are unused for validator-reward. - let _a = 1; - } -} - -// NegativeImbalance: -// Some balance has been subtracted somewhere, needs to be added somewhere else. -pub struct Absorb(T); -impl OnUnbalanced> for Absorb -{ - fn on_nonzero_unbalanced(amount: NegativeImbalanceOf) { - let raw_amount = amount.peek(); - let treasury = >::get(); - if let Some(next_treasury) = treasury.checked_add(&raw_amount) { - >::put(next_treasury); - } else { - // TODO - } - >::deposit_event( - RawEvent::Absorbed( - raw_amount, - >::get() - ) - ); - } -} - -// PositiveImbalance: -// Some balance has been added somewhere, needs to be subtracted somewhere else. -pub struct Reward(T); -impl OnUnbalanced> for Reward -{ - fn on_nonzero_unbalanced(amount: PositiveImbalanceOf) { - let raw_amount = amount.peek(); - let treasury = >::get(); - if let Some(next_treasury) = treasury.checked_sub(&raw_amount) { - >::put(next_treasury); - } else { - // TODO - } - >::deposit_event( - RawEvent::Rewarded( - raw_amount, - >::get() - ) - ); - } -} \ No newline at end of file diff --git a/pallets/mb-session/Cargo.toml b/pallets/mb-session/Cargo.toml deleted file mode 100644 index 744ac3fa4b865..0000000000000 --- a/pallets/mb-session/Cargo.toml +++ /dev/null @@ -1,40 +0,0 @@ -[package] -authors = ['PureStake'] -edition = '2018' -name = 'mb-session' -version = '0.1.0' - -[dependencies] -codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -safe-mix = { default-features = false, version = '1.0.0' } -serde = { version = "1.0.102", features = ["derive"] } - -# primitives -sp-core = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -sp-io = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -sp-runtime = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -sp-std = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -sp-session = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -sp-staking = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -node-primitives = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } - -# frame dependencies -frame-support = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -system = { package = 'frame-system', git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -pallet-balances = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -pallet-session = { features = ["historical"], git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -pallet-authorship = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } - -[features] -default = ['std'] -std = [ - "sp-std/std", - "sp-staking/std", - 'codec/std', - 'frame-support/std', - 'safe-mix/std', - "sp-session/std", - 'system/std', - "pallet-session/std", - "pallet-authorship/std", -] diff --git a/pallets/mb-session/src/lib.rs b/pallets/mb-session/src/lib.rs deleted file mode 100644 index bf6cd72dc4379..0000000000000 --- a/pallets/mb-session/src/lib.rs +++ /dev/null @@ -1,403 +0,0 @@ -#![cfg_attr(not(feature = "std"), no_std)] - -use sp_std::prelude::*; -// use sp_runtime::traits::{OpaqueKeys,Convert}; -use sp_runtime::traits::{SaturatedConversion}; -use frame_support::{decl_module, decl_storage, decl_event, decl_error, debug}; -use frame_support::dispatch::{DispatchResult}; -use frame_support::traits::{Currency,Get}; -use system::{ensure_signed}; - -use sp_core::crypto::KeyTypeId; -use system::offchain::{SubmitSignedTransaction}; - -#[path = "../../../runtime/src/constants.rs"] -#[allow(dead_code)] -mod constants; -use constants::time::{EPOCH_DURATION_IN_BLOCKS}; -use constants::mb_genesis::{VALIDATORS_PER_SESSION}; - -pub const KEY_TYPE: KeyTypeId = KeyTypeId(*b"mbst"); - -type BalanceOf = - <::Currency as Currency<::AccountId>>::Balance; - -pub mod crypto { - pub use super::KEY_TYPE; - use sp_runtime::app_crypto::{app_crypto, sr25519}; - app_crypto!(sr25519, KEY_TYPE); -} - -pub trait Trait: system::Trait + pallet_balances::Trait + pallet_session::Trait { - type Event: From> + Into<::Event>; - type Call: From>; - type SubmitTransaction: SubmitSignedTransaction::Call>; - type Currency: Currency; - type SessionsPerEra: Get; -} - -decl_storage! { - trait Store for Module as MoonbeamStakingModule { - /// The number of Era. - EraIndex: u32; - /// The total validator pool. - Validators: Vec; - /// The current session of an Era. - SessionOfEraIndex: u32; - /// The current Block Index of an Era. - BlockOfEraIndex: u32; - /// The validator set selected for the Era. - SessionValidators get(session_validators): Vec; - /// Number of blocks authored by a given validator in this Era. - SessionValidatorAuthoring: - map hasher(blake2_256) T::AccountId => u32; - /// One to Many Validator -> Endorsers. - ValidatorEndorsers: map hasher(blake2_256) T::AccountId => Vec; - /// One to One Endorser -> Validator. - Endorser: map hasher(blake2_256) T::AccountId => T::AccountId; - /// A timeline of free_balances for an endorser that allows us to calculate - /// the average of free_balance of an era. - /// - /// TODO: Used to select era validators at the start (or end TODO) of an era. - /// We are by now supposing that an endorsement represents all the free_balance - /// of the token holder. - /// When the free_balance of an endorser changes, a new snapshot is created - /// together with the current block_index of the current era. - /// - /// Endorser, Validator => (session_block_index,endorser_balance) - EndorserSnapshots: - double_map hasher(blake2_256) T::AccountId, hasher(blake2_256) T::AccountId => Vec<(u32,BalanceOf)>; - - /// TODO the Treasury balance. It is still unclear if this will be a pallet account or - /// will remain as a Storage balance. - Treasury get(treasury): T::Balance; - } - add_extra_genesis { - config(session_validators): Vec; - config(treasury): T::Balance; - build(|config: &GenesisConfig| { - // set all validators - let _ = >::append(config.session_validators.clone()); - // set initial selected validators - let _ = >::append(config.session_validators.clone()); - // set treasury - >::put(config.treasury); - // set genesis era data - EraIndex::put(1); - BlockOfEraIndex::put(1); - }); - } -} - -decl_error! { - pub enum Error for Module { - AlreadyEndorsing, - NotEndorsing, - } -} - -decl_event!( - pub enum Event - where - AccountId = ::AccountId, - { - BlockAuthored(AccountId), - NewEra(u32), - NewSession(u32), - EndSession(u32), - } -); - -decl_module! { - pub struct Module for enum Call where origin: T::Origin { - - type Error = Error; - fn deposit_event() = default; - - /// Endorsing dispatchable function - pub fn endorse( - origin, to:T::AccountId - ) -> DispatchResult { - let from = ensure_signed(origin)?; - // Check if the Account is already endorsing. - if >::contains_key(&from) { - return Err(Error::::AlreadyEndorsing).map_err(Into::into); - } - // Set One to One endorser->validator association. - >::insert(&from,&to); - // Set One to Many validator->endorsers association. - >::append(&to,vec![&from])?; - // Create a snapshot with the current free balance of the endorser. - Self::set_snapshot(&from,&to,T::Currency::free_balance(&from))?; - Ok(()) - } - - /// Unndorsing dispatchable function - pub fn unendorse( - origin - ) -> DispatchResult { - let from = ensure_signed(origin)?; - // Check if the Account is actively endorsing. - if !>::contains_key(&from) { - return Err(Error::::NotEndorsing).map_err(Into::into); - } - - let validator = >::get(&from); - let mut endorsers = >::get(&validator); - - // Remove One to Many validator->endorsers association - endorsers.retain(|x| x != &from); - >::insert(&validator, endorsers); - // Remove One to One endorser->validator association - >::remove(&from); - // Remove all snapshots associated to the endorser, using the double map prefix - >::remove_prefix(&from); - - Ok(()) - } - - fn offchain_worker(block_number: T::BlockNumber) { - // Set snapshots - Self::offchain_set_snapshots(); - // Select validators off-chain - Self::offchain_validator_selection(block_number); - } - - fn persist_selected_validators( - origin,selected_validators: Vec - ) -> DispatchResult { - ensure_signed(origin)?; - >::put(selected_validators.clone()); - Ok(()) - } - - fn persist_snapshots( - origin,snapshots: Vec<(T::AccountId,T::AccountId,BalanceOf)> - ) -> DispatchResult { - ensure_signed(origin)?; - for s in &snapshots { - Self::set_snapshot(&s.0,&s.1,s.2)?; - } - Ok(()) - } - } -} - -impl Module { - - /// First approach to keep moving forward until we find out how to track BalanceOf - /// changes in real-time. - /// - /// This approach, although functional, is invalid as it has multiple issues like - /// sending signed transactions potentially every block. - /// - /// Other messy ways could be, again a per-block offchain task, pattern matching the - /// >::events() to find pallet_balances events that are registered - /// in the Storage. - fn offchain_set_snapshots() { - let mut output: Vec<(T::AccountId,T::AccountId,BalanceOf)> = vec![]; - let validators = >::get(); - for v in &validators { - let endorsers = >::get(v); - for ed in &endorsers { - let snapshots = >::get(ed,v.clone()); - let len = snapshots.len(); - // Make sure we have a previous block reference in this Era - if len > 0 { - let snapshot_balance = snapshots[len-1].1; - let current_balance = T::Currency::free_balance(ed); - if snapshot_balance != current_balance { - output.push((ed.clone(),v.clone(),current_balance)); - } - } - } - } - // If there are snapshots, send signed transaction - if output.len() > 0 { - let call = Call::persist_snapshots(output); - let res = T::SubmitTransaction::submit_signed(call); - if res.is_empty() { - debug::native::info!("No local accounts found."); - } else { - debug::native::info!("Sending snapshots transaction."); - } - } - } - - /// Offchain task to select validators - fn offchain_validator_selection(block_number: T::BlockNumber) { - // Find out where we are in Era - let current_era: u128 = EraIndex::get() as u128; - let last_block_of_era: u128 = - (current_era * (T::SessionsPerEra::get() as u128) * (EPOCH_DURATION_IN_BLOCKS as u128)).saturated_into(); - let validator_selection_delta: u128 = 5; - let current_block_number: u128 = block_number.saturated_into(); - // When we are 5 blocks away of a new Era, run the validator selection. - if (last_block_of_era - current_block_number) == validator_selection_delta { - // Perform the validator selection - let selected_validators = >::select_validators(); - // Send signed transaction to persist the new validators to the on-chain storage - let call = Call::persist_selected_validators(selected_validators); - let res = T::SubmitTransaction::submit_signed(call); - if res.is_empty() { - debug::native::info!("No local accounts found."); - } else { - debug::native::info!("Sending selected validator transaction."); - } - } - } - - /// Sets a snapshot using the current era's block index and the Account free_balance. - fn set_snapshot( - endorser: &T::AccountId, validator: &T::AccountId, amount: BalanceOf - ) -> DispatchResult { - >::append(&endorser,&validator, - vec![(BlockOfEraIndex::get(),amount)])?; - Ok(()) - } - /// Calculates a single endorser weighted balance for the era by measuring the - /// block index distances. - fn calculate_endorsement( - endorser: &T::AccountId, validator: &T::AccountId - ) -> f64 { - - let duration: u32 = EPOCH_DURATION_IN_BLOCKS; - let points = >::get(endorser,validator); - let points_dim: usize = points.len(); - - if points_dim == 0 { - return 0 as f64; - } - - let n: usize = points_dim-1; - let (points,n) = Self::set_snapshot_boundaries(duration,n,points); - let mut previous: (u32,BalanceOf) = (0,BalanceOf::::from(0)); - // Find the distances between snapshots, weight the free_balance against them. - // Finally sum all values. - let mut endorsement: f64 = points.iter().map(|p| { - let out: f64; - if previous != (0,BalanceOf::::from(0)) { - let delta = p.0-previous.0; - let w = delta as f64 / duration as f64; - out = w * previous.1.saturated_into() as f64; - } else { - out = 0 as f64; - } - previous = *p; - out - }) - .sum::(); - // The above iterative approach excludes the last block, sum it to the result. - endorsement += (1 as f64 / duration as f64) * points[n].1.saturated_into() as f64; - endorsement - } - /// Selects a new validator set based on their amount of weighted endorsement. - fn select_validators() -> Vec { - let validators = >::get(); - // Get the calculated endorsement per validator. - let mut selected_validators = validators.iter().map(|v| { - let endorsers = >::get(v); - let total_validator_endorsement = endorsers.iter().map(|ed| { - Self::calculate_endorsement(ed,v) - }) - .sum::(); - (total_validator_endorsement,v) - }) - .collect::>(); - // Sort descendant validators by amount. - selected_validators.sort_by(|(x0, _y0), (x1, _y1)| x0.partial_cmp(&x1).unwrap()); - selected_validators.reverse(); - // Take the by-configuration amount of validators. - selected_validators.into_iter().take(VALIDATORS_PER_SESSION as usize) - .map(|(_x,y)| y.clone()) - .collect::>() - } - /// Conditionally set the boundary balances to complete a snapshot series. - /// (if no snapshot is defined on block 1 or {era_len} indexes). - fn set_snapshot_boundaries( - duration: u32, - mut last_index: usize, - mut collection: Vec<(u32,BalanceOf)> - ) -> (Vec<(u32,BalanceOf)>,usize) { - - if collection[0].0 != 1 { - collection.insert(0,(1,BalanceOf::::from(0))); - last_index += 1; - } - if collection[last_index].0 != duration { - collection.push((duration,collection[last_index].1)); - } - (collection,last_index) - } - /// All snapshots are reset on era change with a single checkpoint of the - /// current endorser's Account free_balance. - fn reset_snapshots() { - let validators = >::get(); - for validator in validators.iter() { - let endorsers = >::get(validator); - for endorser in endorsers.iter() { - >::insert(endorser,validator,vec![( - 1 as u32, - T::Currency::free_balance(endorser) - )]); - } - } - } -} - -pub struct SessionManager(T); -impl pallet_session::SessionManager for SessionManager { - fn new_session(new_index: u32) -> Option> { - - >::deposit_event( - RawEvent::NewSession(new_index) - ); - - if new_index > 1 { - let current_era = EraIndex::get(); - if new_index > (current_era * (T::SessionsPerEra::get() as u32)) { - // Era change - // Reset SessionOfEraIndex to 1 - SessionOfEraIndex::put(1); - // Reset BlockOfEraIndex to 1 - BlockOfEraIndex::put(1); - // Increase the EraIndex by 1 - let new_era_idx = EraIndex::get().checked_add(1) - .ok_or("SessionOfEraIndex Overflow").unwrap(); - EraIndex::put(new_era_idx); - // Reset all snapshots - >::reset_snapshots(); - } else { - // Same Era, next session. Increase SessionOfEraIndex by 1. - let new_era_session_idx = SessionOfEraIndex::get().checked_add(1) - .ok_or("SessionOfEraIndex Overflow").unwrap(); - SessionOfEraIndex::put(new_era_session_idx); - } - Some(>::get()) - } else { - None - } - } - - fn end_session(end_index: u32) { - >::deposit_event( - RawEvent::EndSession(end_index) - ); - } -} - -pub struct AuthorshipEventHandler(T); -impl pallet_authorship::EventHandler for AuthorshipEventHandler { - fn note_author(author: T::AccountId) { - let authored_blocks = - >::get(&author).checked_add(1).ok_or("Overflow").unwrap(); - >::insert(&author,authored_blocks); - BlockOfEraIndex::mutate(|x| *x += 1); - // >::deposit_event( - // RawEvent::BlockAuthored(author) - // ); - } - fn note_uncle(_author: T::AccountId, _age: u32) { - - } -} \ No newline at end of file diff --git a/primitives/Cargo.toml b/primitives/Cargo.toml deleted file mode 100644 index def9b268dab86..0000000000000 --- a/primitives/Cargo.toml +++ /dev/null @@ -1,21 +0,0 @@ -[package] -name = "node-primitives" -version = "2.0.0" -authors = ["Parity Technologies "] -edition = "2018" -license = "GPL-3.0" - -[dependencies] -sp-core = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02' } -sp-runtime = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02' } - -[dev-dependencies] -sp-serializer = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02' } -pretty_assertions = "0.6.1" - -[features] -default = ["std"] -std = [ - "sp-core/std", - "sp-runtime/std", -] diff --git a/primitives/src/lib.rs b/primitives/src/lib.rs deleted file mode 100644 index 97e8f50c27145..0000000000000 --- a/primitives/src/lib.rs +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Substrate is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Substrate. If not, see . - -//! Low-level types used throughout the Substrate code. - -#![warn(missing_docs)] - -#![cfg_attr(not(feature = "std"), no_std)] - -use sp_runtime::{ - generic, traits::{Verify, BlakeTwo256, IdentifyAccount}, OpaqueExtrinsic, MultiSignature -}; - -/// An index to a block. -pub type BlockNumber = u32; - -/// Alias to 512-bit hash when used in the context of a transaction signature on the chain. -pub type Signature = MultiSignature; - -/// Some way of identifying an account on the chain. We intentionally make it equivalent -/// to the public key of our transaction signing scheme. -pub type AccountId = <::Signer as IdentifyAccount>::AccountId; - -/// The type for looking up accounts. We don't expect more than 4 billion of them. -pub type AccountIndex = u32; - -/// Balance of an account. -pub type Balance = u128; - -/// Type used for expressing timestamp. -pub type Moment = u64; - -/// Index of a transaction in the chain. -pub type Index = u32; - -/// A hash of some data used by the chain. -pub type Hash = sp_core::H256; - -/// A timestamp: milliseconds since the unix epoch. -/// `u64` is enough to represent a duration of half a billion years, when the -/// time scale is milliseconds. -pub type Timestamp = u64; - -/// Digest item type. -pub type DigestItem = generic::DigestItem; -/// Header type. -pub type Header = generic::Header; -/// Block type. -pub type Block = generic::Block; -/// Block ID. -pub type BlockId = generic::BlockId; diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml deleted file mode 100644 index 9b78a35d363c5..0000000000000 --- a/runtime/Cargo.toml +++ /dev/null @@ -1,118 +0,0 @@ -[package] -name = "moonbeam-runtime" -version = "0.1.0" -authors = ["PureStake"] -edition = "2018" -license = "Unlicense" - -# third-party dependencies -[dependencies] -codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -integer-sqrt = { version = "0.1.2" } -rustc-hex = { version = "2.0", optional = true } -serde = { version = "1.0.102", optional = true } - -# primitives -sp-authority-discovery = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -sp-consensus-babe = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -sp-block-builder = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -sp-inherents = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -node-primitives = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -sp-offchain = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -sp-core = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -sp-std = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -sp-api = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -sp-runtime = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -sp-staking = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -sp-keyring = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', optional = true } -sp-session = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -sp-transaction-pool = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -sp-version = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } - -# frame dependencies -frame-executive = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -frame-support = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -frame-system = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -frame-system-rpc-runtime-api = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -pallet-authority-discovery = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -pallet-authorship = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -pallet-babe = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -pallet-balances = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -pallet-contracts = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -pallet-contracts-primitives = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -pallet-contracts-rpc-runtime-api = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -pallet-finality-tracker = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -pallet-grandpa = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -pallet-im-online = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -pallet-indices = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -pallet-offences = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -pallet-randomness-collective-flip = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -pallet-recovery = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -pallet-session = { features = ["historical"], git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -pallet-staking = { features = ["migrate"], git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -pallet-staking-reward-curve = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02' } -pallet-sudo = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -pallet-timestamp = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -pallet-utility = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -pallet-transaction-payment = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -pallet-transaction-payment-rpc-runtime-api = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -pallet-vesting = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02', default-features = false } -mb-core = { version = "0.1.0", default-features = false, path = "../pallets/mb-core", package = "mb-core" } -mb-session = { version = "0.1.0", default-features = false, path = "../pallets/mb-session", package = "mb-session" } - -[build-dependencies] -wasm-builder-runner = { package = "substrate-wasm-builder-runner", version = "1.0.5" } - -[dev-dependencies] -sp-io = { git = 'https://github.com/paritytech/substrate.git', rev = '992aea815a753da256a9c0bff053df408532df02' } - -[features] -default = ["std"] -std = [ - "sp-authority-discovery/std", - "pallet-authority-discovery/std", - "pallet-authorship/std", - "sp-consensus-babe/std", - "pallet-babe/std", - "pallet-balances/std", - "sp-block-builder/std", - "codec/std", - "pallet-contracts/std", - "pallet-contracts-primitives/std", - "pallet-contracts-rpc-runtime-api/std", - "frame-executive/std", - "pallet-finality-tracker/std", - "pallet-grandpa/std", - "pallet-im-online/std", - "pallet-indices/std", - "sp-inherents/std", - "node-primitives/std", - "sp-offchain/std", - "pallet-offences/std", - "sp-core/std", - "pallet-randomness-collective-flip/std", - "sp-std/std", - "rustc-hex", - "serde", - "pallet-session/std", - "sp-api/std", - "sp-runtime/std", - "sp-staking/std", - "pallet-staking/std", - "sp-keyring", - "sp-session/std", - "pallet-sudo/std", - "frame-support/std", - "frame-system-rpc-runtime-api/std", - "frame-system/std", - "pallet-timestamp/std", - "pallet-transaction-payment-rpc-runtime-api/std", - "pallet-transaction-payment/std", - "sp-transaction-pool/std", - "pallet-utility/std", - "sp-version/std", - "pallet-recovery/std", - "pallet-vesting/std", - "mb-core/std", - "mb-session/std", -] diff --git a/runtime/build.rs b/runtime/build.rs deleted file mode 100644 index 39f7f56feb0b1..0000000000000 --- a/runtime/build.rs +++ /dev/null @@ -1,10 +0,0 @@ -use wasm_builder_runner::WasmBuilder; - -fn main() { - WasmBuilder::new() - .with_current_project() - .with_wasm_builder_from_crates("1.0.9") - .export_heap_base() - .import_memory() - .build() -} diff --git a/runtime/src/constants.rs b/runtime/src/constants.rs deleted file mode 100644 index b672ac768a52a..0000000000000 --- a/runtime/src/constants.rs +++ /dev/null @@ -1,75 +0,0 @@ -//! A set of constant values used in substrate runtime. - -pub mod mb_genesis { - use node_primitives::{Balance}; - use super::currency::{GLMR}; - /// 8 decimals for 500_000 glmr units - pub const TOTAL_GLMR_SUPPLY: Balance = 10_000_000 * GLMR; - pub const TREASURY_FUND: Balance = TOTAL_GLMR_SUPPLY / 5; - pub const REWARD_PER_YEAR: Balance = 250_000 * GLMR; - - pub const VALIDATORS_PER_SESSION: u8 = 2; -} - -/// Money matters. -pub mod currency { - use node_primitives::Balance; - - pub const MILLICENTS: Balance = 1_000_000_000; - pub const CENTS: Balance = 1_000 * MILLICENTS; // assume this is worth about a cent. - pub const DOLLARS: Balance = 100 * CENTS; - - pub const MILLIGLMR: Balance = 1_000; - pub const CENTIGLMR: Balance = 1_000 * MILLIGLMR; - pub const GLMR: Balance = 100 * CENTIGLMR; -} - -/// Time. -pub mod time { - use node_primitives::{Moment, BlockNumber}; - - /// Since BABE is probabilistic this is the average expected block time that - /// we are targetting. Blocks will be produced at a minimum duration defined - /// by `SLOT_DURATION`, but some slots will not be allocated to any - /// authority and hence no block will be produced. We expect to have this - /// block time on average following the defined slot duration and the value - /// of `c` configured for BABE (where `1 - c` represents the probability of - /// a slot being empty). - /// This value is only used indirectly to define the unit constants below - /// that are expressed in blocks. The rest of the code should use - /// `SLOT_DURATION` instead (like the Timestamp pallet for calculating the - /// minimum period). - /// - /// If using BABE with secondary slots (default) then all of the slots will - /// always be assigned, in which case `MILLISECS_PER_BLOCK` and - /// `SLOT_DURATION` should have the same value. - /// - /// - pub const MILLISECS_PER_BLOCK: Moment = 3000; - pub const SECS_PER_BLOCK: Moment = MILLISECS_PER_BLOCK / 1000; - - pub const SLOT_DURATION: Moment = MILLISECS_PER_BLOCK; - - // 1 in 4 blocks (on average, not counting collisions) will be primary BABE blocks. - pub const PRIMARY_PROBABILITY: (u64, u64) = (1, 4); - - // Sessions are set low (1 per minute) for debugging purposes. - // As a block is produced every 3 seconds by configuration, a new session will occur every X blocks. - pub const EPOCH_DURATION_IN_BLOCKS: BlockNumber = 5 * MINUTES; - pub const EPOCH_DURATION_IN_SLOTS: u64 = { - const SLOT_FILL_RATE: f64 = MILLISECS_PER_BLOCK as f64 / SLOT_DURATION as f64; - - (EPOCH_DURATION_IN_BLOCKS as f64 * SLOT_FILL_RATE) as u64 - }; - - // These time units are defined in number of blocks. - pub const MINUTES: BlockNumber = 60 / (SECS_PER_BLOCK as BlockNumber); - pub const HOURS: BlockNumber = MINUTES * 60; - pub const DAYS: BlockNumber = HOURS * 24; - - // epochs/session per era - pub const EPOCH_PER_ERA: u8 = 1; - - // convenience year in milliseconds. TODO. - pub const MILLISECS_PER_YEAR: u64 = 3660 * 24 * 365 * 1000; -} diff --git a/runtime/src/impls.rs b/runtime/src/impls.rs deleted file mode 100644 index 31a008208e2e1..0000000000000 --- a/runtime/src/impls.rs +++ /dev/null @@ -1,174 +0,0 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Substrate is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Substrate. If not, see . - -//! Some configurable implementations as associated type for the substrate runtime. -use sp_std::prelude::*; - -use sp_runtime::traits::{Convert, Saturating}; -use sp_runtime::{Fixed64, Perbill,RuntimeDebug}; -use frame_support::{traits::{OnUnbalanced, Currency, Get}, weights::Weight}; -use codec::{HasCompact, Encode, Decode}; -use sp_staking::offence::{OffenceDetails}; - -use node_primitives::Balance; -use crate::{Balances, System, Authorship, MaximumBlockWeight, NegativeImbalance, BalanceOf}; - -pub struct Author; -impl OnUnbalanced for Author { - fn on_nonzero_unbalanced(amount: NegativeImbalance) { - Balances::resolve_creating(&Authorship::author(), amount); - } -} - -/// Struct that handles the conversion of Balance -> `u64`. This is used for staking's election -/// calculation. -pub struct CurrencyToVoteHandler; - -impl CurrencyToVoteHandler { - fn factor() -> Balance { (Balances::total_issuance() / u64::max_value() as Balance).max(1) } -} - -impl Convert for CurrencyToVoteHandler { - fn convert(x: Balance) -> u64 { (x / Self::factor()) as u64 } -} - -impl Convert for CurrencyToVoteHandler { - fn convert(x: u128) -> Balance { x * Self::factor() } -} - -/// Convert from weight to balance via a simple coefficient multiplication -/// The associated type C encapsulates a constant in units of balance per weight -pub struct LinearWeightToFee(sp_std::marker::PhantomData); - -impl> Convert for LinearWeightToFee { - fn convert(w: Weight) -> Balance { - // substrate-node a weight of 10_000 (smallest non-zero weight) to be mapped to 10^7 units of - // fees, hence: - let coefficient = C::get(); - Balance::from(w).saturating_mul(coefficient) - } -} - -/// Update the given multiplier based on the following formula -/// -/// diff = (previous_block_weight - target_weight) -/// v = 0.00004 -/// next_weight = weight * (1 + (v . diff) + (v . diff)^2 / 2) -/// -/// Where `target_weight` must be given as the `Get` implementation of the `T` generic type. -/// https://research.web3.foundation/en/latest/polkadot/Token%20Economics/#relay-chain-transaction-fees -pub struct TargetedFeeAdjustment(sp_std::marker::PhantomData); - -impl> Convert for TargetedFeeAdjustment { - fn convert(multiplier: Fixed64) -> Fixed64 { - let block_weight = System::all_extrinsics_weight(); - let max_weight = MaximumBlockWeight::get(); - let target_weight = (T::get() * max_weight) as u128; - let block_weight = block_weight as u128; - - // determines if the first_term is positive - let positive = block_weight >= target_weight; - let diff_abs = block_weight.max(target_weight) - block_weight.min(target_weight); - // diff is within u32, safe. - let diff = Fixed64::from_rational(diff_abs as i64, max_weight as u64); - let diff_squared = diff.saturating_mul(diff); - - // 0.00004 = 4/100_000 = 40_000/10^9 - let v = Fixed64::from_rational(4, 100_000); - // 0.00004^2 = 16/10^10 ~= 2/10^9. Taking the future /2 into account, then it is just 1 - // parts from a billionth. - let v_squared_2 = Fixed64::from_rational(1, 1_000_000_000); - - let first_term = v.saturating_mul(diff); - // It is very unlikely that this will exist (in our poor perbill estimate) but we are giving - // it a shot. - let second_term = v_squared_2.saturating_mul(diff_squared); - - if positive { - // Note: this is merely bounded by how big the multiplier and the inner value can go, - // not by any economical reasoning. - let excess = first_term.saturating_add(second_term); - multiplier.saturating_add(excess) - } else { - // Proof: first_term > second_term. Safe subtraction. - let negative = first_term - second_term; - multiplier.saturating_sub(negative) - // despite the fact that apply_to saturates weight (final fee cannot go below 0) - // it is crucially important to stop here and don't further reduce the weight fee - // multiplier. While at -1, it means that the network is so un-congested that all - // transactions have no weight fee. We stop here and only increase if the network - // became more busy. - .max(Fixed64::from_rational(-1, 1)) - } - } -} - -// All below are trait implemenations that we need to satisfy for the historical feature of the pallet-session -// and by offences. - -/// The amount of exposure (to slashing) than an individual nominator has. -#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, RuntimeDebug)] -pub struct IndividualExposure { - /// The stash account of the nominator in question. - who: AccountId, - /// Amount of funds exposed. - #[codec(compact)] - value: Balance, -} - -/// A snapshot of the stake backing a single validator in the system. -#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Default, RuntimeDebug)] -pub struct Exposure { - /// The total balance backing this validator. - #[codec(compact)] - pub total: Balance, - /// The validator's own stash that is exposed. - #[codec(compact)] - pub own: Balance, - /// The portions of nominators stashes that are exposed. - pub others: Vec>, -} - -/// A typed conversion from stash account ID to the current exposure of nominators -/// on that account. -pub struct ExposureOf(sp_std::marker::PhantomData); -impl Convert>>> - for ExposureOf -{ - fn convert(_validator: T::AccountId) -> Option>> { - None - } -} - -pub struct StakingOffences(sp_std::marker::PhantomData); -impl sp_staking::offence::OnOffenceHandler> for StakingOffences where - T: pallet_session::Trait::AccountId>, - T: pallet_session::historical::Trait< - FullIdentification = Exposure<::AccountId, BalanceOf>, - FullIdentificationOf = ExposureOf, - >, - T::SessionHandler: pallet_session::SessionHandler<::AccountId>, - T::SessionManager: pallet_session::SessionManager<::AccountId>, - T::ValidatorIdOf: Convert<::AccountId, Option<::AccountId>> -{ - fn on_offence( - _offenders: &[OffenceDetails>], - _slash_fraction: &[Perbill], - _slash_session: u32, - ) { - - } -} \ No newline at end of file diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs deleted file mode 100644 index 640d633e21748..0000000000000 --- a/runtime/src/lib.rs +++ /dev/null @@ -1,634 +0,0 @@ -#![cfg_attr(not(feature = "std"), no_std)] -// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256. -#![recursion_limit="256"] - -// Make the WASM binary available. -#[cfg(feature = "std")] -include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); - -use sp_std::prelude::*; -use sp_core::OpaqueMetadata; -use sp_runtime::{ - ApplyExtrinsicResult, transaction_validity::TransactionValidity, generic, create_runtime_str, - impl_opaque_keys, -}; -use sp_runtime::traits::{ - self, BlakeTwo256, Block as BlockT, SaturatedConversion, StaticLookup, - ConvertInto, OpaqueKeys -}; -use sp_api::impl_runtime_apis; -use sp_version::RuntimeVersion; -use sp_inherents::{InherentData, CheckInherentsResult}; -use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId; - -use frame_system::offchain::TransactionSubmitter; - -use frame_support::{ - construct_runtime, parameter_types, debug, - weights::Weight, - traits::{SplitTwoWays, Currency, Randomness}, -}; - -#[cfg(feature = "std")] -use sp_version::NativeVersion; -use pallet_contracts_rpc_runtime_api::ContractExecResult; -use sp_core::u32_trait::{_1, _4}; - -use pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo; - -// A few exports that help ease life for downstream crates. -#[cfg(any(feature = "std", test))] -pub use sp_runtime::BuildStorage; -pub use pallet_timestamp::Call as TimestampCall; -pub use pallet_balances::Call as BalancesCall; -pub use sp_runtime::{Permill, Perbill}; - -use pallet_grandpa::AuthorityList as GrandpaAuthorityList; -use pallet_grandpa::fg_primitives; -use pallet_im_online::sr25519::{AuthorityId as ImOnlineId}; -pub use pallet_staking::StakerStatus; -pub use pallet_contracts::Gas as ContractsGas; - -use node_primitives::{AccountIndex, Balance, BlockNumber, Hash, Index, Moment}; -pub use node_primitives::{AccountId, Signature}; - -pub mod constants; -pub use constants::{time::*, currency::*, mb_genesis::*}; - -/// Importing the moonbeam core pallet -pub use mb_core; -pub use mb_session; - -/// Implementations of some helper traits passed into runtime modules as associated types. -pub mod impls; -use impls::{Author, LinearWeightToFee, TargetedFeeAdjustment, Exposure, ExposureOf, StakingOffences}; - -impl_opaque_keys! { - pub struct SessionKeys { - pub grandpa: Grandpa, - pub babe: Babe, - pub im_online: ImOnline, - pub authority_discovery: AuthorityDiscovery, - } -} - -/// This runtime version. -pub const VERSION: RuntimeVersion = RuntimeVersion { - spec_name: create_runtime_str!("moonbeam-runtime"), - impl_name: create_runtime_str!("moonbeam-runtime"), - authoring_version: 1, - spec_version: 1, - impl_version: 1, - apis: RUNTIME_API_VERSIONS, -}; - -/// The version information 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(), - } -} - -type NegativeImbalance = >::NegativeImbalance; - -pub type DealWithFees = SplitTwoWays< - Balance, - NegativeImbalance, - _4, mb_core::Absorb, // 4 parts (80%) goes to the treasury. - _1, Author, // 1 part (20%) goes to the block author. ->; - -parameter_types! { - pub const BlockHashCount: BlockNumber = 250; - pub const MaximumBlockWeight: Weight = 1_000_000; - pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75); - pub const MaximumBlockLength: u32 = 5 * 1024 * 1024; - pub const Version: RuntimeVersion = VERSION; -} - -impl frame_system::Trait for Runtime { - type Origin = Origin; - type Call = Call; - type Index = Index; - type BlockNumber = BlockNumber; - type Hash = Hash; - type Hashing = BlakeTwo256; - type AccountId = AccountId; - type Lookup = Indices; - type Header = generic::Header; - type Event = Event; - type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type MaximumBlockLength = MaximumBlockLength; - type AvailableBlockRatio = AvailableBlockRatio; - type Version = Version; - type ModuleToIndex = ModuleToIndex; - type AccountData = pallet_balances::AccountData; - type OnNewAccount = (); - type OnReapAccount = (); -} - -parameter_types! { - // One storage item; value is size 4+4+16+32 bytes = 56 bytes. - pub const MultisigDepositBase: Balance = 30 * CENTIGLMR; - // Additional storage item size of 32 bytes. - pub const MultisigDepositFactor: Balance = 5 * CENTIGLMR; - pub const MaxSignatories: u16 = 100; -} - -impl pallet_utility::Trait for Runtime { - type Event = Event; - type Call = Call; - type Currency = Balances; - type MultisigDepositBase = MultisigDepositBase; - type MultisigDepositFactor = MultisigDepositFactor; - type MaxSignatories = MaxSignatories; -} - -parameter_types! { - pub const EpochDuration: u64 = EPOCH_DURATION_IN_SLOTS; - pub const ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK; -} - -impl pallet_babe::Trait for Runtime { - type EpochDuration = EpochDuration; - type ExpectedBlockTime = ExpectedBlockTime; - type EpochChangeTrigger = pallet_babe::ExternalTrigger; -} - -impl pallet_grandpa::Trait for Runtime { - type Event = Event; -} - -parameter_types! { - /// How much an index costs. - pub const IndexDeposit: Balance = 1 * GLMR; -} - -impl pallet_indices::Trait for Runtime { - /// The type for recording indexing into the account enumeration. If this ever overflows, there - /// will be problems! - type AccountIndex = AccountIndex; - /// The ubiquitous event type. - type Event = Event; - /// The currency type. - type Currency = Balances; - /// How much an index costs. - type Deposit = IndexDeposit; -} - -parameter_types! { - pub const MinimumPeriod: Moment = SLOT_DURATION / 2; -} - -impl pallet_timestamp::Trait for Runtime { - /// A timestamp: milliseconds since the unix epoch. - type Moment = Moment; - type OnTimestampSet = Babe; - type MinimumPeriod = MinimumPeriod; -} - -parameter_types! { - pub const ExistentialDeposit: Balance = 500; -} - -impl pallet_balances::Trait for Runtime { - type Balance = Balance; - type Event = Event; - type DustRemoval = (); - type ExistentialDeposit = ExistentialDeposit; - type AccountStore = frame_system::Module; -} - -parameter_types! { - pub const TransactionBaseFee: Balance = 1 * CENTIGLMR; - pub const TransactionByteFee: Balance = 10 * MILLIGLMR; - // setting this to zero will disable the weight fee. - pub const WeightFeeCoefficient: Balance = 0; // original at 1_000 - // for a sane configuration, this should always be less than `AvailableBlockRatio`. - pub const TargetBlockFullness: Perbill = Perbill::from_percent(25); -} - -impl pallet_transaction_payment::Trait for Runtime { - type Currency = Balances; - type OnTransactionPayment = DealWithFees; - type TransactionBaseFee = TransactionBaseFee; - type TransactionByteFee = TransactionByteFee; - type WeightToFee = LinearWeightToFee; - type FeeMultiplierUpdate = TargetedFeeAdjustment; -} - -parameter_types! { - pub const UncleGenerations: BlockNumber = 5; -} - -impl pallet_authorship::Trait for Runtime { - type FindAuthor = pallet_session::FindAccountFromAuthorIndex; - type UncleGenerations = UncleGenerations; - type FilterUncle = (); - type EventHandler = (mb_session::AuthorshipEventHandler, ImOnline); -} - -parameter_types! { - pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(17); -} - -impl pallet_session::Trait for Runtime { - type Event = Event; - type ValidatorId = ::AccountId; - type ValidatorIdOf = ConvertInto; - type ShouldEndSession = Babe; - type SessionManager = mb_session::SessionManager; - type SessionHandler = ::KeyTypeIdProviders; - type Keys = SessionKeys; - type DisabledValidatorsThreshold = DisabledValidatorsThreshold; -} - -impl pallet_session::historical::Trait for Runtime { - type FullIdentification = Exposure; - type FullIdentificationOf = ExposureOf; -} - -parameter_types! { - pub const ContractTransactionBaseFee: Balance = 1 * CENTIGLMR; - pub const ContractTransactionByteFee: Balance = 10 * MILLIGLMR; - pub const ContractFee: Balance = 1 * CENTIGLMR; - pub const TombstoneDeposit: Balance = 1 * GLMR; - pub const RentByteFee: Balance = 1 * GLMR; - pub const RentDepositOffset: Balance = 1000 * GLMR; - pub const SurchargeReward: Balance = 150 * GLMR; -} - -impl pallet_contracts::Trait for Runtime { - type Currency = Balances; - type Time = Timestamp; - type Randomness = RandomnessCollectiveFlip; - type Call = Call; - type Event = Event; - type DetermineContractAddress = pallet_contracts::SimpleAddressDeterminer; - type ComputeDispatchFee = pallet_contracts::DefaultDispatchFeeComputor; - type TrieIdGenerator = pallet_contracts::TrieIdFromParentCounter; - type GasPayment = (); - type RentPayment = (); - type SignedClaimHandicap = pallet_contracts::DefaultSignedClaimHandicap; - type TombstoneDeposit = TombstoneDeposit; - type StorageSizeOffset = pallet_contracts::DefaultStorageSizeOffset; - type RentByteFee = RentByteFee; - type RentDepositOffset = RentDepositOffset; - type SurchargeReward = SurchargeReward; - type TransactionBaseFee = ContractTransactionBaseFee; - type TransactionByteFee = ContractTransactionByteFee; - type ContractFee = ContractFee; - type CallBaseFee = pallet_contracts::DefaultCallBaseFee; - type InstantiateBaseFee = pallet_contracts::DefaultInstantiateBaseFee; - type MaxDepth = pallet_contracts::DefaultMaxDepth; - type MaxValueSize = pallet_contracts::DefaultMaxValueSize; - type BlockGasLimit = pallet_contracts::DefaultBlockGasLimit; -} - -pub type SubmitTransaction = TransactionSubmitter; - -parameter_types! { - pub const SessionDuration: BlockNumber = EPOCH_DURATION_IN_SLOTS as _; -} - -impl pallet_im_online::Trait for Runtime { - type AuthorityId = ImOnlineId; - type Event = Event; - type Call = Call; - type SubmitTransaction = SubmitTransaction; - type SessionDuration = SessionDuration; - type ReportUnresponsiveness = Offences; -} - -impl pallet_offences::Trait for Runtime { - type Event = Event; - type IdentificationTuple = pallet_session::historical::IdentificationTuple; - type OnOffenceHandler = StakingOffences; -} - -impl pallet_authority_discovery::Trait for Runtime {} - -parameter_types! { - pub const WindowSize: BlockNumber = 101; - pub const ReportLatency: BlockNumber = 1000; -} - -impl pallet_finality_tracker::Trait for Runtime { - type OnFinalizationStalled = (); - type WindowSize = WindowSize; - type ReportLatency = ReportLatency; -} - -impl frame_system::offchain::CreateTransaction for Runtime { - type Public = ::Signer; - type Signature = Signature; - - fn create_transaction>( - call: Call, - public: Self::Public, - account: AccountId, - index: Index, - ) -> Option<(Call, ::SignaturePayload)> { - // take the biggest period possible. - let period = BlockHashCount::get() - .checked_next_power_of_two() - .map(|c| c / 2) - .unwrap_or(2) as u64; - let current_block = System::block_number() - .saturated_into::() - // The `System::block_number` is initialized with `n+1`, - // so the actual block number is `n`. - .saturating_sub(1); - let tip = 0; - let extra: SignedExtra = ( - frame_system::CheckVersion::::new(), - frame_system::CheckGenesis::::new(), - frame_system::CheckEra::::from(generic::Era::mortal(period, current_block)), - frame_system::CheckNonce::::from(index), - frame_system::CheckWeight::::new(), - pallet_transaction_payment::ChargeTransactionPayment::::from(tip), - Default::default(), - ); - let raw_payload = SignedPayload::new(call, extra).map_err(|e| { - debug::warn!("Unable to create signed payload: {:?}", e); - }).ok()?; - let signature = TSigner::sign(public, &raw_payload)?; - let address = Indices::unlookup(account); - let (call, extra, _) = raw_payload.deconstruct(); - Some((call, (address, signature, extra))) - } -} - -parameter_types! { - pub const ConfigDepositBase: Balance = 5 * GLMR; - pub const FriendDepositFactor: Balance = 50 * GLMR; - pub const MaxFriends: u16 = 9; - pub const RecoveryDeposit: Balance = 5 * GLMR; -} - -impl pallet_recovery::Trait for Runtime { - type Event = Event; - type Call = Call; - type Currency = Balances; - type ConfigDepositBase = ConfigDepositBase; - type FriendDepositFactor = FriendDepositFactor; - type MaxFriends = MaxFriends; - type RecoveryDeposit = RecoveryDeposit; -} - -impl pallet_vesting::Trait for Runtime { - type Event = Event; - type Currency = Balances; - type BlockNumberToBalance = ConvertInto; -} - -impl pallet_sudo::Trait for Runtime { - type Event = Event; - type Call = Call; -} - -impl mb_core::Trait for Runtime { - type Currency = Balances; - type Event = Event; -} - -parameter_types! { - pub const SessionsPerEra: u8 = EPOCH_PER_ERA; -} - -type SubmitMBTransaction = TransactionSubmitter< - mb_session::crypto::Public, - Runtime, - UncheckedExtrinsic ->; - -pub type BalanceOf = - <::Currency as Currency<::AccountId>>::Balance; - -impl mb_session::Trait for Runtime { - type Currency = Balances; - type SubmitTransaction = SubmitMBTransaction; - type Call = Call; - type Event = Event; - type SessionsPerEra = SessionsPerEra; -} - - -construct_runtime!( - pub enum Runtime where - Block = Block, - NodeBlock = node_primitives::Block, - UncheckedExtrinsic = UncheckedExtrinsic - { - System: frame_system::{Module, Call, Config, Storage, Event}, - Utility: pallet_utility::{Module, Call, Storage, Event}, - Babe: pallet_babe::{Module, Call, Storage, Config, Inherent(Timestamp)}, - Timestamp: pallet_timestamp::{Module, Call, Storage, Inherent}, - Authorship: pallet_authorship::{Module, Call, Storage, Inherent}, - Indices: pallet_indices::{Module, Call, Storage, Config, Event}, - Balances: pallet_balances::{Module, Call, Storage, Config, Event}, - TransactionPayment: pallet_transaction_payment::{Module, Storage}, - Session: pallet_session::{Module, Call, Storage, Event, Config}, - FinalityTracker: pallet_finality_tracker::{Module, Call, Inherent}, - Grandpa: pallet_grandpa::{Module, Call, Storage, Config, Event}, - Contracts: pallet_contracts::{Module, Call, Config, Storage, Event}, - Sudo: pallet_sudo::{Module, Call, Config, Storage, Event}, - ImOnline: pallet_im_online::{Module, Call, Storage, Event, ValidateUnsigned, Config}, - AuthorityDiscovery: pallet_authority_discovery::{Module, Call, Config}, - Offences: pallet_offences::{Module, Call, Storage, Event}, - RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Module, Call, Storage}, - Recovery: pallet_recovery::{Module, Call, Storage, Event}, - Vesting: pallet_vesting::{Module, Call, Storage, Event, Config}, - MoonbeamCore: mb_core::{Module, Call, Storage, Event, Config}, - MoonbeamSession: mb_session::{Module, Call, Storage, Event, Config}, - } -); - -/// The address format for describing accounts. -pub type Address = ::Source; -/// Block header type as expected by this runtime. -pub type Header = generic::Header; -/// Block type as expected by this runtime. -pub type Block = generic::Block; -/// A Block signed with a Justification -pub type SignedBlock = generic::SignedBlock; -/// BlockId type as expected by this runtime. -pub type BlockId = generic::BlockId; -/// The SignedExtension to the basic transaction logic. -pub type SignedExtra = ( - frame_system::CheckVersion, - frame_system::CheckGenesis, - frame_system::CheckEra, - frame_system::CheckNonce, - frame_system::CheckWeight, - pallet_transaction_payment::ChargeTransactionPayment, - pallet_contracts::CheckBlockGasLimit, -); -/// Unchecked extrinsic type as expected by this runtime. -pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; -/// Extrinsic type that has already been checked. -pub type CheckedExtrinsic = generic::CheckedExtrinsic; -/// Executive: handles dispatch to the various modules. -pub type Executive = frame_executive::Executive, Runtime, AllModules>; -/// The payload being signed in transactions. -pub type SignedPayload = generic::SignedPayload; - -impl_runtime_apis! { - impl sp_api::Core for Runtime { - fn version() -> RuntimeVersion { - VERSION - } - - fn execute_block(block: Block) { - Executive::execute_block(block) - } - - fn initialize_block(header: &::Header) { - Executive::initialize_block(header) - } - } - - impl sp_api::Metadata for Runtime { - fn metadata() -> OpaqueMetadata { - Runtime::metadata().into() - } - } - - impl sp_block_builder::BlockBuilder for Runtime { - fn apply_extrinsic(extrinsic: ::Extrinsic) -> ApplyExtrinsicResult { - Executive::apply_extrinsic(extrinsic) - } - - fn apply_trusted_extrinsic(extrinsic: ::Extrinsic) -> ApplyExtrinsicResult { - Executive::apply_trusted_extrinsic(extrinsic) - } - - fn finalize_block() -> ::Header { - Executive::finalize_block() - } - - fn inherent_extrinsics(data: InherentData) -> Vec<::Extrinsic> { - data.create_extrinsics() - } - - fn check_inherents(block: Block, data: InherentData) -> CheckInherentsResult { - data.check_extrinsics(&block) - } - - fn random_seed() -> ::Hash { - RandomnessCollectiveFlip::random_seed() - } - } - - impl sp_transaction_pool::runtime_api::TaggedTransactionQueue for Runtime { - fn validate_transaction(tx: ::Extrinsic) -> TransactionValidity { - Executive::validate_transaction(tx) - } - } - - impl sp_offchain::OffchainWorkerApi for Runtime { - fn offchain_worker(header: &::Header) { - Executive::offchain_worker(header) - } - } - - impl fg_primitives::GrandpaApi for Runtime { - fn grandpa_authorities() -> GrandpaAuthorityList { - Grandpa::grandpa_authorities() - } - } - - impl sp_consensus_babe::BabeApi for Runtime { - fn configuration() -> sp_consensus_babe::BabeConfiguration { - // The choice of `c` parameter (where `1 - c` represents the - // probability of a slot being empty), is done in accordance to the - // slot duration and expected target block time, for safely - // resisting network delays of maximum two seconds. - // - sp_consensus_babe::BabeConfiguration { - slot_duration: Babe::slot_duration(), - epoch_length: EpochDuration::get(), - c: PRIMARY_PROBABILITY, - genesis_authorities: Babe::authorities(), - randomness: Babe::randomness(), - secondary_slots: true, - } - } - - fn current_epoch_start() -> sp_consensus_babe::SlotNumber { - Babe::current_epoch_start() - } - } - - impl sp_authority_discovery::AuthorityDiscoveryApi for Runtime { - fn authorities() -> Vec { - AuthorityDiscovery::authorities() - } - } - - impl frame_system_rpc_runtime_api::AccountNonceApi for Runtime { - fn account_nonce(account: AccountId) -> Index { - System::account_nonce(account) - } - } - - impl pallet_contracts_rpc_runtime_api::ContractsApi - for Runtime - { - fn call( - origin: AccountId, - dest: AccountId, - value: Balance, - gas_limit: u64, - input_data: Vec, - ) -> ContractExecResult { - let exec_result = - Contracts::bare_call(origin, dest.into(), value, gas_limit, input_data); - match exec_result { - Ok(v) => ContractExecResult::Success { - status: v.status, - data: v.data, - }, - Err(_) => ContractExecResult::Error, - } - } - - fn get_storage( - address: AccountId, - key: [u8; 32], - ) -> pallet_contracts_primitives::GetStorageResult { - Contracts::get_storage(address, key) - } - - fn rent_projection( - address: AccountId, - ) -> pallet_contracts_primitives::RentProjectionResult { - Contracts::rent_projection(address) - } - } - - impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi< - Block, - Balance, - UncheckedExtrinsic, - > for Runtime { - fn query_info(uxt: UncheckedExtrinsic, len: u32) -> RuntimeDispatchInfo { - TransactionPayment::query_info(uxt, len) - } - } - - impl sp_session::SessionKeys for Runtime { - fn generate_session_keys(seed: Option>) -> Vec { - SessionKeys::generate(seed) - } - - fn decode_session_keys( - encoded: Vec, - ) -> Option, sp_core::crypto::KeyTypeId)>> { - SessionKeys::decode_into_raw_public_keys(&encoded) - } - } -} \ No newline at end of file From 98a862508f9faedba84b7395c42101eadd3a4c36 Mon Sep 17 00:00:00 2001 From: Crystalin Date: Wed, 6 May 2020 15:16:50 -0400 Subject: [PATCH 4/5] Adds Node/Runtime template from 2.0.0-alpha.7 branch --- Cargo.toml | 7 + node/Cargo.toml | 78 +++++++++ node/build.rs | 7 + node/src/chain_spec.rs | 131 +++++++++++++++ node/src/cli.rs | 11 ++ node/src/command.rs | 80 +++++++++ node/src/main.rs | 12 ++ node/src/service.rs | 249 ++++++++++++++++++++++++++++ runtime/Cargo.toml | 151 +++++++++++++++++ runtime/build.rs | 10 ++ runtime/src/lib.rs | 366 +++++++++++++++++++++++++++++++++++++++++ 11 files changed, 1102 insertions(+) create mode 100644 Cargo.toml create mode 100644 node/Cargo.toml create mode 100644 node/build.rs create mode 100644 node/src/chain_spec.rs create mode 100644 node/src/cli.rs create mode 100644 node/src/command.rs create mode 100644 node/src/main.rs create mode 100644 node/src/service.rs create mode 100644 runtime/Cargo.toml create mode 100644 runtime/build.rs create mode 100644 runtime/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000000000..9c337cd2f10a3 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,7 @@ +[workspace] +members = [ + 'node', + 'runtime', +] +[profile.release] +panic = 'unwind' diff --git a/node/Cargo.toml b/node/Cargo.toml new file mode 100644 index 0000000000000..ed722f1015baf --- /dev/null +++ b/node/Cargo.toml @@ -0,0 +1,78 @@ +[package] +authors = ['PureStake'] +build = 'build.rs' +description = 'Substrate Moonbeam Node ' +edition = '2018' +homepage = 'https://moonbeam.network' +license = 'Unlicense' +name = 'node-moonbeam' +repository = 'https://github.com/PureStake/moonbeam/' +version = '0.1.0' + +[package.metadata.docs.rs] +targets = ['x86_64-unknown-linux-gnu'] + +[dependencies] +futures = '0.3.4' +log = '0.4.8' +structopt = '0.3.8' + +[dependencies.node-moonbeam-runtime] +path = '../runtime' +version = '0.1.0' + +[dependencies.sc-basic-authorship] +version = '0.8.0-alpha.7' + +[dependencies.sc-cli] +version = '0.8.0-alpha.7' + +[dependencies.sc-client-api] +version = '2.0.0-alpha.7' + +[dependencies.sc-consensus] +version = '0.8.0-alpha.7' + +[dependencies.sc-consensus-aura] +version = '0.8.0-alpha.7' + +[dependencies.sc-executor] +version = '0.8.0-alpha.7' + +[dependencies.sc-finality-grandpa] +version = '0.8.0-alpha.7' + +[dependencies.sc-network] +version = '0.8.0-alpha.7' + +[dependencies.sc-service] +version = '0.8.0-alpha.7' + +[dependencies.sc-transaction-pool] +version = '2.0.0-alpha.7' + +[dependencies.sp-consensus] +version = '0.8.0-alpha.7' + +[dependencies.sp-consensus-aura] +version = '0.8.0-alpha.7' + +[dependencies.sp-core] +version = '2.0.0-alpha.7' + +[dependencies.sp-finality-grandpa] +version = '2.0.0-alpha.7' + +[dependencies.sp-inherents] +version = '2.0.0-alpha.7' + +[dependencies.sp-runtime] +version = '2.0.0-alpha.7' + +[dependencies.sp-transaction-pool] +version = '2.0.0-alpha.7' +[build-dependencies.substrate-build-script-utils] +version = '2.0.0-alpha.7' + +[[bin]] +name = 'node-moonbeam' diff --git a/node/build.rs b/node/build.rs new file mode 100644 index 0000000000000..e3bfe3116bf28 --- /dev/null +++ b/node/build.rs @@ -0,0 +1,7 @@ +use substrate_build_script_utils::{generate_cargo_keys, rerun_if_git_head_changed}; + +fn main() { + generate_cargo_keys(); + + rerun_if_git_head_changed(); +} diff --git a/node/src/chain_spec.rs b/node/src/chain_spec.rs new file mode 100644 index 0000000000000..8492b96dd18a8 --- /dev/null +++ b/node/src/chain_spec.rs @@ -0,0 +1,131 @@ +use node_moonbeam_runtime::{ + AccountId, AuraConfig, BalancesConfig, GenesisConfig, GrandpaConfig, Signature, SudoConfig, + SystemConfig, WASM_BINARY, +}; +use sc_service::ChainType; +use sp_consensus_aura::sr25519::AuthorityId as AuraId; +use sp_core::{sr25519, Pair, Public}; +use sp_finality_grandpa::AuthorityId as GrandpaId; +use sp_runtime::traits::{IdentifyAccount, Verify}; + +// Note this is the URL for the telemetry server +//const STAGING_TELEMETRY_URL: &str = "wss://telemetry.polkadot.io/submit/"; + +/// Specialized `ChainSpec`. This is a specialization of the general Substrate ChainSpec type. +pub type ChainSpec = sc_service::GenericChainSpec; + +/// Helper function to generate a crypto pair from seed +pub fn get_from_seed(seed: &str) -> ::Public { + TPublic::Pair::from_string(&format!("//{}", seed), None) + .expect("static values are valid; qed") + .public() +} + +type AccountPublic = ::Signer; + +/// Helper function to generate an account ID from seed +pub fn get_account_id_from_seed(seed: &str) -> AccountId +where + AccountPublic: From<::Public>, +{ + AccountPublic::from(get_from_seed::(seed)).into_account() +} + +/// Helper function to generate an authority key for Aura +pub fn authority_keys_from_seed(s: &str) -> (AuraId, GrandpaId) { + (get_from_seed::(s), get_from_seed::(s)) +} + +pub fn development_config() -> ChainSpec { + ChainSpec::from_genesis( + "Development", + "dev", + ChainType::Development, + || { + testnet_genesis( + vec![authority_keys_from_seed("Alice")], + get_account_id_from_seed::("Alice"), + vec![ + get_account_id_from_seed::("Alice"), + get_account_id_from_seed::("Bob"), + get_account_id_from_seed::("Alice//stash"), + get_account_id_from_seed::("Bob//stash"), + ], + true, + ) + }, + vec![], + None, + None, + None, + None, + ) +} + +pub fn local_testnet_config() -> ChainSpec { + ChainSpec::from_genesis( + "Local Testnet", + "local_testnet", + ChainType::Local, + || { + testnet_genesis( + vec![ + authority_keys_from_seed("Alice"), + authority_keys_from_seed("Bob"), + ], + get_account_id_from_seed::("Alice"), + vec![ + get_account_id_from_seed::("Alice"), + get_account_id_from_seed::("Bob"), + get_account_id_from_seed::("Charlie"), + get_account_id_from_seed::("Dave"), + get_account_id_from_seed::("Eve"), + get_account_id_from_seed::("Ferdie"), + get_account_id_from_seed::("Alice//stash"), + get_account_id_from_seed::("Bob//stash"), + get_account_id_from_seed::("Charlie//stash"), + get_account_id_from_seed::("Dave//stash"), + get_account_id_from_seed::("Eve//stash"), + get_account_id_from_seed::("Ferdie//stash"), + ], + true, + ) + }, + vec![], + None, + None, + None, + None, + ) +} + +fn testnet_genesis( + initial_authorities: Vec<(AuraId, GrandpaId)>, + root_key: AccountId, + endowed_accounts: Vec, + _enable_println: bool, +) -> GenesisConfig { + GenesisConfig { + system: Some(SystemConfig { + code: WASM_BINARY.to_vec(), + changes_trie_config: Default::default(), + }), + balances: Some(BalancesConfig { + balances: endowed_accounts + .iter() + .cloned() + .map(|k| (k, 1 << 60)) + .collect(), + }), + aura: Some(AuraConfig { + authorities: initial_authorities.iter().map(|x| (x.0.clone())).collect(), + }), + grandpa: Some(GrandpaConfig { + authorities: initial_authorities + .iter() + .map(|x| (x.1.clone(), 1)) + .collect(), + }), + sudo: Some(SudoConfig { key: root_key }), + } +} diff --git a/node/src/cli.rs b/node/src/cli.rs new file mode 100644 index 0000000000000..0091ef7d75912 --- /dev/null +++ b/node/src/cli.rs @@ -0,0 +1,11 @@ +use sc_cli::{RunCmd, Subcommand}; +use structopt::StructOpt; + +#[derive(Debug, StructOpt)] +pub struct Cli { + #[structopt(subcommand)] + pub subcommand: Option, + + #[structopt(flatten)] + pub run: RunCmd, +} diff --git a/node/src/command.rs b/node/src/command.rs new file mode 100644 index 0000000000000..cb8ec94097913 --- /dev/null +++ b/node/src/command.rs @@ -0,0 +1,80 @@ +// Copyright 2017-2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +use crate::chain_spec; +use crate::cli::Cli; +use crate::service; +use sc_cli::SubstrateCli; + +impl SubstrateCli for Cli { + fn impl_name() -> &'static str { + "Substrate Node" + } + + fn impl_version() -> &'static str { + env!("SUBSTRATE_CLI_IMPL_VERSION") + } + + fn description() -> &'static str { + env!("CARGO_PKG_DESCRIPTION") + } + + fn author() -> &'static str { + env!("CARGO_PKG_AUTHORS") + } + + fn support_url() -> &'static str { + "support.anonymous.an" + } + + fn copyright_start_year() -> i32 { + 2017 + } + + fn executable_name() -> &'static str { + env!("CARGO_PKG_NAME") + } + + fn load_spec(&self, id: &str) -> Result, String> { + Ok(match id { + "dev" => Box::new(chain_spec::development_config()), + "" | "local" => Box::new(chain_spec::local_testnet_config()), + path => Box::new(chain_spec::ChainSpec::from_json_file( + std::path::PathBuf::from(path), + )?), + }) + } +} + +/// Parse and run command line arguments +pub fn run() -> sc_cli::Result<()> { + let cli = Cli::from_args(); + + match &cli.subcommand { + Some(subcommand) => { + let runner = cli.create_runner(subcommand)?; + runner.run_subcommand(subcommand, |config| Ok(new_full_start!(config).0)) + } + None => { + let runner = cli.create_runner(&cli.run)?; + runner.run_node( + service::new_light, + service::new_full, + node_moonbeam_runtime::VERSION, + ) + } + } +} diff --git a/node/src/main.rs b/node/src/main.rs new file mode 100644 index 0000000000000..369e6932a0308 --- /dev/null +++ b/node/src/main.rs @@ -0,0 +1,12 @@ +//! Substrate Node Template CLI library. +#![warn(missing_docs)] + +mod chain_spec; +#[macro_use] +mod service; +mod cli; +mod command; + +fn main() -> sc_cli::Result<()> { + command::run() +} diff --git a/node/src/service.rs b/node/src/service.rs new file mode 100644 index 0000000000000..347d2ee44d370 --- /dev/null +++ b/node/src/service.rs @@ -0,0 +1,249 @@ +//! Service and ServiceFactory implementation. Specialized wrapper over substrate service. + +use node_moonbeam_runtime::{self, opaque::Block, RuntimeApi}; +use sc_client_api::ExecutorProvider; +use sc_consensus::LongestChain; +use sc_executor::native_executor_instance; +pub use sc_executor::NativeExecutor; +use sc_finality_grandpa::{ + FinalityProofProvider as GrandpaFinalityProofProvider, SharedVoterState, + StorageAndProofProvider, +}; +use sc_service::{error::Error as ServiceError, AbstractService, Configuration, ServiceBuilder}; +use sp_consensus_aura::sr25519::AuthorityPair as AuraPair; +use sp_inherents::InherentDataProviders; +use std::sync::Arc; +use std::time::Duration; + +// Our native executor instance. +native_executor_instance!( + pub Executor, + node_moonbeam_runtime::api::dispatch, + node_moonbeam_runtime::native_version, +); + +/// Starts a `ServiceBuilder` for a full service. +/// +/// Use this macro if you don't actually need the full service, but just the builder in order to +/// be able to perform chain operations. +macro_rules! new_full_start { + ($config:expr) => {{ + use sp_consensus_aura::sr25519::AuthorityPair as AuraPair; + use std::sync::Arc; + + let mut import_setup = None; + let inherent_data_providers = sp_inherents::InherentDataProviders::new(); + + let builder = sc_service::ServiceBuilder::new_full::< + node_moonbeam_runtime::opaque::Block, + node_moonbeam_runtime::RuntimeApi, + crate::service::Executor, + >($config)? + .with_select_chain(|_config, backend| Ok(sc_consensus::LongestChain::new(backend.clone())))? + .with_transaction_pool(|config, client, _fetcher, prometheus_registry| { + let pool_api = sc_transaction_pool::FullChainApi::new(client.clone()); + Ok(sc_transaction_pool::BasicPool::new( + config, + std::sync::Arc::new(pool_api), + prometheus_registry, + )) + })? + .with_import_queue( + |_config, client, mut select_chain, _transaction_pool, spawn_task_handle| { + let select_chain = select_chain + .take() + .ok_or_else(|| sc_service::Error::SelectChainRequired)?; + + let (grandpa_block_import, grandpa_link) = sc_finality_grandpa::block_import( + client.clone(), + &(client.clone() as Arc<_>), + select_chain, + )?; + + let aura_block_import = + sc_consensus_aura::AuraBlockImport::<_, _, _, AuraPair>::new( + grandpa_block_import.clone(), + client.clone(), + ); + + let import_queue = sc_consensus_aura::import_queue::<_, _, _, AuraPair, _>( + sc_consensus_aura::slot_duration(&*client)?, + aura_block_import, + Some(Box::new(grandpa_block_import.clone())), + None, + client, + inherent_data_providers.clone(), + spawn_task_handle, + )?; + + import_setup = Some((grandpa_block_import, grandpa_link)); + + Ok(import_queue) + }, + )?; + + (builder, import_setup, inherent_data_providers) + }}; +} + +/// Builds a new service for a full client. +pub fn new_full(config: Configuration) -> Result { + let role = config.role.clone(); + let force_authoring = config.force_authoring; + let name = config.network.node_name.clone(); + let disable_grandpa = config.disable_grandpa; + + let (builder, mut import_setup, inherent_data_providers) = new_full_start!(config); + + let (block_import, grandpa_link) = import_setup.take().expect( + "Link Half and Block Import are present for Full Services or setup failed before. qed", + ); + + let service = builder + .with_finality_proof_provider(|client, backend| { + // GenesisAuthoritySetProvider is implemented for StorageAndProofProvider + let provider = client as Arc>; + Ok(Arc::new(GrandpaFinalityProofProvider::new(backend, provider)) as _) + })? + .build()?; + + if role.is_authority() { + let proposer = + sc_basic_authorship::ProposerFactory::new(service.client(), service.transaction_pool()); + + let client = service.client(); + let select_chain = service + .select_chain() + .ok_or(ServiceError::SelectChainRequired)?; + + let can_author_with = + sp_consensus::CanAuthorWithNativeVersion::new(client.executor().clone()); + + let aura = sc_consensus_aura::start_aura::<_, _, _, _, _, AuraPair, _, _, _>( + sc_consensus_aura::slot_duration(&*client)?, + client, + select_chain, + block_import, + proposer, + service.network(), + inherent_data_providers.clone(), + force_authoring, + service.keystore(), + can_author_with, + )?; + + // the AURA authoring task is considered essential, i.e. if it + // fails we take down the service with it. + service.spawn_essential_task("aura", aura); + } + + // if the node isn't actively participating in consensus then it doesn't + // need a keystore, regardless of which protocol we use below. + let keystore = if role.is_authority() { + Some(service.keystore()) + } else { + None + }; + + let grandpa_config = sc_finality_grandpa::Config { + // FIXME #1578 make this available through chainspec + gossip_duration: Duration::from_millis(333), + justification_period: 512, + name: Some(name), + observer_enabled: false, + keystore, + is_authority: role.is_network_authority(), + }; + + let enable_grandpa = !disable_grandpa; + if enable_grandpa { + // start the full GRANDPA voter + // NOTE: non-authorities could run the GRANDPA observer protocol, but at + // this point the full voter should provide better guarantees of block + // and vote data availability than the observer. The observer has not + // been tested extensively yet and having most nodes in a network run it + // could lead to finality stalls. + let grandpa_config = sc_finality_grandpa::GrandpaParams { + config: grandpa_config, + link: grandpa_link, + network: service.network(), + inherent_data_providers: inherent_data_providers.clone(), + telemetry_on_connect: Some(service.telemetry_on_connect_stream()), + voting_rule: sc_finality_grandpa::VotingRulesBuilder::default().build(), + prometheus_registry: service.prometheus_registry(), + shared_voter_state: SharedVoterState::empty(), + }; + + // the GRANDPA voter task is considered infallible, i.e. + // if it fails we take down the service with it. + service.spawn_essential_task( + "grandpa-voter", + sc_finality_grandpa::run_grandpa_voter(grandpa_config)?, + ); + } else { + sc_finality_grandpa::setup_disabled_grandpa( + service.client(), + &inherent_data_providers, + service.network(), + )?; + } + + Ok(service) +} + +/// Builds a new service for a light client. +pub fn new_light(config: Configuration) -> Result { + let inherent_data_providers = InherentDataProviders::new(); + + ServiceBuilder::new_light::(config)? + .with_select_chain(|_config, backend| Ok(LongestChain::new(backend.clone())))? + .with_transaction_pool(|config, client, fetcher, prometheus_registry| { + let fetcher = fetcher + .ok_or_else(|| "Trying to start light transaction pool without active fetcher")?; + + let pool_api = sc_transaction_pool::LightChainApi::new(client.clone(), fetcher.clone()); + let pool = sc_transaction_pool::BasicPool::with_revalidation_type( + config, + Arc::new(pool_api), + prometheus_registry, + sc_transaction_pool::RevalidationType::Light, + ); + Ok(pool) + })? + .with_import_queue_and_fprb( + |_config, client, backend, fetcher, _select_chain, _tx_pool, spawn_task_handle| { + let fetch_checker = fetcher + .map(|fetcher| fetcher.checker().clone()) + .ok_or_else(|| { + "Trying to start light import queue without active fetch checker" + })?; + let grandpa_block_import = sc_finality_grandpa::light_block_import( + client.clone(), + backend, + &(client.clone() as Arc<_>), + Arc::new(fetch_checker), + )?; + let finality_proof_import = grandpa_block_import.clone(); + let finality_proof_request_builder = + finality_proof_import.create_finality_proof_request_builder(); + + let import_queue = sc_consensus_aura::import_queue::<_, _, _, AuraPair, _>( + sc_consensus_aura::slot_duration(&*client)?, + grandpa_block_import, + None, + Some(Box::new(finality_proof_import)), + client, + inherent_data_providers.clone(), + spawn_task_handle, + )?; + + Ok((import_queue, finality_proof_request_builder)) + }, + )? + .with_finality_proof_provider(|client, backend| { + // GenesisAuthoritySetProvider is implemented for StorageAndProofProvider + let provider = client as Arc>; + Ok(Arc::new(GrandpaFinalityProofProvider::new(backend, provider)) as _) + })? + .build() +} diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml new file mode 100644 index 0000000000000..f89d0a051084e --- /dev/null +++ b/runtime/Cargo.toml @@ -0,0 +1,151 @@ +[package] +authors = ['PureStake'] +edition = '2018' +homepage = 'https://moonbeam.network' +license = 'Unlicense' +name = 'node-moonbeam-runtime' +repository = 'https://github.com/PureStake/moonbeam/' +version = '0.1.0' + +[dependencies.aura] +default-features = false +package = 'pallet-aura' +version = '2.0.0-alpha.7' + +[dependencies.balances] +default-features = false +package = 'pallet-balances' +version = '2.0.0-alpha.7' + +[dependencies.codec] +default-features = false +features = ['derive'] +package = 'parity-scale-codec' +version = '1.3.0' + +[dependencies.frame-executive] +default-features = false +version = '2.0.0-alpha.7' + +[dependencies.frame-support] +default-features = false +version = '2.0.0-alpha.7' + +[dependencies.grandpa] +default-features = false +package = 'pallet-grandpa' +version = '2.0.0-alpha.7' + +[dependencies.randomness-collective-flip] +default-features = false +package = 'pallet-randomness-collective-flip' +version = '2.0.0-alpha.7' + +[dependencies.serde] +features = ['derive'] +optional = true +version = '1.0.101' + +[dependencies.sp-api] +default-features = false +version = '2.0.0-alpha.7' + +[dependencies.sp-block-builder] +default-features = false +version = '2.0.0-alpha.7' + +[dependencies.sp-consensus-aura] +default-features = false +version = '0.8.0-alpha.7' + +[dependencies.sp-core] +default-features = false +version = '2.0.0-alpha.7' + +[dependencies.sp-inherents] +default-features = false +version = '2.0.0-alpha.7' + +[dependencies.sp-io] +default-features = false +version = '2.0.0-alpha.7' + +[dependencies.sp-offchain] +default-features = false +version = '2.0.0-alpha.7' + +[dependencies.sp-runtime] +default-features = false +version = '2.0.0-alpha.7' + +[dependencies.sp-session] +default-features = false +version = '2.0.0-alpha.7' + +[dependencies.sp-std] +default-features = false +version = '2.0.0-alpha.7' + +[dependencies.sp-transaction-pool] +default-features = false +version = '2.0.0-alpha.7' + +[dependencies.sp-version] +default-features = false +version = '2.0.0-alpha.7' + +[dependencies.sudo] +default-features = false +package = 'pallet-sudo' +version = '2.0.0-alpha.7' + +[dependencies.system] +default-features = false +package = 'frame-system' +version = '2.0.0-alpha.7' + +[dependencies.timestamp] +default-features = false +package = 'pallet-timestamp' +version = '2.0.0-alpha.7' + +[dependencies.transaction-payment] +default-features = false +package = 'pallet-transaction-payment' +version = '2.0.0-alpha.7' + +[build-dependencies.wasm-builder-runner] +package = 'substrate-wasm-builder-runner' +version = '1.0.5' + +[package.metadata.docs.rs] +targets = ['x86_64-unknown-linux-gnu'] + +[features] +default = ['std'] +std = [ + 'aura/std', + 'balances/std', + 'codec/std', + 'frame-executive/std', + 'frame-support/std', + 'grandpa/std', + 'randomness-collective-flip/std', + 'serde', + 'sp-api/std', + 'sp-block-builder/std', + 'sp-consensus-aura/std', + 'sp-core/std', + 'sp-inherents/std', + 'sp-io/std', + 'sp-offchain/std', + 'sp-runtime/std', + 'sp-session/std', + 'sp-std/std', + 'sp-transaction-pool/std', + 'sp-version/std', + 'sudo/std', + 'system/std', + 'timestamp/std', + 'transaction-payment/std', +] diff --git a/runtime/build.rs b/runtime/build.rs new file mode 100644 index 0000000000000..39f7f56feb0b1 --- /dev/null +++ b/runtime/build.rs @@ -0,0 +1,10 @@ +use wasm_builder_runner::WasmBuilder; + +fn main() { + WasmBuilder::new() + .with_current_project() + .with_wasm_builder_from_crates("1.0.9") + .export_heap_base() + .import_memory() + .build() +} diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs new file mode 100644 index 0000000000000..2f478f470b6a5 --- /dev/null +++ b/runtime/src/lib.rs @@ -0,0 +1,366 @@ +//! The Substrate Node Moonbeam runtime. This can be compiled with `#[no_std]`, ready for Wasm. + +#![cfg_attr(not(feature = "std"), no_std)] +// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256. +#![recursion_limit = "256"] + +// Make the WASM binary available. +#[cfg(feature = "std")] +include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); + +use grandpa::fg_primitives; +use grandpa::AuthorityList as GrandpaAuthorityList; +use sp_api::impl_runtime_apis; +use sp_consensus_aura::sr25519::AuthorityId as AuraId; +use sp_core::OpaqueMetadata; +use sp_runtime::traits::{ + BlakeTwo256, Block as BlockT, ConvertInto, IdentifyAccount, IdentityLookup, Verify, +}; +use sp_runtime::{ + create_runtime_str, generic, impl_opaque_keys, + transaction_validity::{TransactionSource, TransactionValidity}, + ApplyExtrinsicResult, MultiSignature, +}; +use sp_std::prelude::*; +#[cfg(feature = "std")] +use sp_version::NativeVersion; +use sp_version::RuntimeVersion; + +// A few exports that help ease life for downstream crates. +pub use balances::Call as BalancesCall; +pub use frame_support::{ + construct_runtime, parameter_types, + traits::Randomness, + weights::{ + constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND}, + Weight, + }, + StorageValue, +}; +#[cfg(any(feature = "std", test))] +pub use sp_runtime::BuildStorage; +pub use sp_runtime::{Perbill, Permill}; +pub use timestamp::Call as TimestampCall; + +/// An index to a block. +pub type BlockNumber = u32; + +/// Alias to 512-bit hash when used in the context of a transaction signature on the chain. +pub type Signature = MultiSignature; + +/// Some way of identifying an account on the chain. We intentionally make it equivalent +/// to the public key of our transaction signing scheme. +pub type AccountId = <::Signer as IdentifyAccount>::AccountId; + +/// The type for looking up accounts. We don't expect more than 4 billion of them, but you +/// never know... +pub type AccountIndex = u32; + +/// Balance of an account. +pub type Balance = u128; + +/// Index of a transaction in the chain. +pub type Index = u32; + +/// A hash of some data used by the chain. +pub type Hash = sp_core::H256; + +/// Digest item type. +pub type DigestItem = generic::DigestItem; + +/// 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 data structures. +pub mod opaque { + use super::*; + + pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic; + + /// Opaque block header type. + pub type Header = generic::Header; + /// Opaque block type. + pub type Block = generic::Block; + /// Opaque block identifier type. + pub type BlockId = generic::BlockId; + + impl_opaque_keys! { + pub struct SessionKeys { + pub aura: Aura, + pub grandpa: Grandpa, + } + } +} + +/// This runtime version. +pub const VERSION: RuntimeVersion = RuntimeVersion { + spec_name: create_runtime_str!("node-moonbeam"), + impl_name: create_runtime_str!("node-moonbeam"), + authoring_version: 1, + spec_version: 1, + impl_version: 1, + apis: RUNTIME_API_VERSIONS, + transaction_version: 1, +}; + +pub const MILLISECS_PER_BLOCK: u64 = 6000; + +pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK; + +// These time units are defined in number of blocks. +pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber); +pub const HOURS: BlockNumber = MINUTES * 60; +pub const DAYS: BlockNumber = HOURS * 24; + +/// The version information 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(), + } +} + +parameter_types! { + pub const BlockHashCount: BlockNumber = 250; + /// We allow for 2 seconds of compute with a 6 second average block time. + pub const MaximumBlockWeight: Weight = 2 * WEIGHT_PER_SECOND; + pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75); + pub const MaximumBlockLength: u32 = 5 * 1024 * 1024; + pub const Version: RuntimeVersion = VERSION; +} + +impl system::Trait for Runtime { + /// The identifier used to distinguish between accounts. + type AccountId = AccountId; + /// The aggregated dispatch type that is available for extrinsics. + type Call = Call; + /// The lookup mechanism to get account ID from whatever is passed in dispatchers. + type Lookup = IdentityLookup; + /// The index type for storing how many extrinsics an account has signed. + type Index = Index; + /// 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 type. + type Header = generic::Header; + /// The ubiquitous event type. + type Event = Event; + /// The ubiquitous origin type. + type Origin = Origin; + /// Maximum number of block number to block hash mappings to keep (oldest pruned first). + type BlockHashCount = BlockHashCount; + /// Maximum weight of each block. + type MaximumBlockWeight = MaximumBlockWeight; + /// The weight of database operations that the runtime can invoke. + type DbWeight = RocksDbWeight; + /// The weight of the overhead invoked on the block import process, independent of the + /// extrinsics included in that block. + type BlockExecutionWeight = BlockExecutionWeight; + /// The base weight of any extrinsic processed by the runtime, independent of the + /// logic of that extrinsic. (Signature verification, nonce increment, fee, etc...) + type ExtrinsicBaseWeight = ExtrinsicBaseWeight; + /// Maximum size of all encoded transactions (in bytes) that are allowed in one block. + type MaximumBlockLength = MaximumBlockLength; + /// Portion of the block weight that is available to all normal transactions. + type AvailableBlockRatio = AvailableBlockRatio; + /// Version of the runtime. + type Version = Version; + /// Converts a module to the index of the module in `construct_runtime!`. + /// + /// This type is being generated by `construct_runtime!`. + type ModuleToIndex = ModuleToIndex; + /// What to do if a new account is created. + type OnNewAccount = (); + /// What to do if an account is fully reaped from the system. + type OnKilledAccount = (); + /// The data to be stored in an account. + type AccountData = balances::AccountData; +} + +impl aura::Trait for Runtime { + type AuthorityId = AuraId; +} + +impl grandpa::Trait for Runtime { + type Event = Event; +} + +parameter_types! { + pub const MinimumPeriod: u64 = SLOT_DURATION / 2; +} + +impl timestamp::Trait for Runtime { + /// A timestamp: milliseconds since the unix epoch. + type Moment = u64; + type OnTimestampSet = Aura; + type MinimumPeriod = MinimumPeriod; +} + +parameter_types! { + pub const ExistentialDeposit: u128 = 500; +} + +impl balances::Trait for Runtime { + /// The type for recording an account's balance. + type Balance = Balance; + /// The ubiquitous event type. + type Event = Event; + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; +} + +parameter_types! { + pub const TransactionByteFee: Balance = 1; +} + +impl transaction_payment::Trait for Runtime { + type Currency = balances::Module; + type OnTransactionPayment = (); + type TransactionByteFee = TransactionByteFee; + type WeightToFee = ConvertInto; + type FeeMultiplierUpdate = (); +} + +impl sudo::Trait for Runtime { + type Event = Event; + type Call = Call; +} + +construct_runtime!( + pub enum Runtime where + Block = Block, + NodeBlock = opaque::Block, + UncheckedExtrinsic = UncheckedExtrinsic + { + System: system::{Module, Call, Config, Storage, Event}, + RandomnessCollectiveFlip: randomness_collective_flip::{Module, Call, Storage}, + Timestamp: timestamp::{Module, Call, Storage, Inherent}, + Aura: aura::{Module, Config, Inherent(Timestamp)}, + Grandpa: grandpa::{Module, Call, Storage, Config, Event}, + Balances: balances::{Module, Call, Storage, Config, Event}, + TransactionPayment: transaction_payment::{Module, Storage}, + Sudo: sudo::{Module, Call, Config, Storage, Event}, + } +); + +/// The address format for describing accounts. +pub type Address = AccountId; +/// Block header type as expected by this runtime. +pub type Header = generic::Header; +/// Block type as expected by this runtime. +pub type Block = generic::Block; +/// A Block signed with a Justification +pub type SignedBlock = generic::SignedBlock; +/// BlockId type as expected by this runtime. +pub type BlockId = generic::BlockId; +/// The SignedExtension to the basic transaction logic. +pub type SignedExtra = ( + system::CheckVersion, + system::CheckGenesis, + system::CheckEra, + system::CheckNonce, + system::CheckWeight, + transaction_payment::ChargeTransactionPayment, +); +/// Unchecked extrinsic type as expected by this runtime. +pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; +/// Extrinsic type that has already been checked. +pub type CheckedExtrinsic = generic::CheckedExtrinsic; +/// Executive: handles dispatch to the various modules. +pub type Executive = + frame_executive::Executive, Runtime, AllModules>; + +impl_runtime_apis! { + impl sp_api::Core for Runtime { + fn version() -> RuntimeVersion { + VERSION + } + + fn execute_block(block: Block) { + Executive::execute_block(block) + } + + fn initialize_block(header: &::Header) { + Executive::initialize_block(header) + } + } + + impl sp_api::Metadata for Runtime { + fn metadata() -> OpaqueMetadata { + Runtime::metadata().into() + } + } + + impl sp_block_builder::BlockBuilder for Runtime { + fn apply_extrinsic(extrinsic: ::Extrinsic) -> ApplyExtrinsicResult { + Executive::apply_extrinsic(extrinsic) + } + + fn finalize_block() -> ::Header { + Executive::finalize_block() + } + + fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<::Extrinsic> { + data.create_extrinsics() + } + + fn check_inherents( + block: Block, + data: sp_inherents::InherentData, + ) -> sp_inherents::CheckInherentsResult { + data.check_extrinsics(&block) + } + + fn random_seed() -> ::Hash { + RandomnessCollectiveFlip::random_seed() + } + } + + impl sp_transaction_pool::runtime_api::TaggedTransactionQueue for Runtime { + fn validate_transaction( + source: TransactionSource, + tx: ::Extrinsic, + ) -> TransactionValidity { + Executive::validate_transaction(source, tx) + } + } + + impl sp_offchain::OffchainWorkerApi for Runtime { + fn offchain_worker(header: &::Header) { + Executive::offchain_worker(header) + } + } + + impl sp_consensus_aura::AuraApi for Runtime { + fn slot_duration() -> u64 { + Aura::slot_duration() + } + + fn authorities() -> Vec { + Aura::authorities() + } + } + + impl sp_session::SessionKeys for Runtime { + fn generate_session_keys(seed: Option>) -> Vec { + opaque::SessionKeys::generate(seed) + } + + fn decode_session_keys( + encoded: Vec, + ) -> Option, sp_core::crypto::KeyTypeId)>> { + opaque::SessionKeys::decode_into_raw_public_keys(&encoded) + } + } + + impl fg_primitives::GrandpaApi for Runtime { + fn grandpa_authorities() -> GrandpaAuthorityList { + Grandpa::grandpa_authorities() + } + } +} From 31905be972ba8affbd3085f95af7372216992753 Mon Sep 17 00:00:00 2001 From: Crystalin Date: Thu, 7 May 2020 18:22:12 -0400 Subject: [PATCH 5/5] Adds EVM pallet to runtime --- node/Cargo.toml | 5 +++++ node/src/chain_spec.rs | 22 ++++++++++++++++++---- runtime/Cargo.toml | 6 ++++++ runtime/src/lib.rs | 31 +++++++++++++++++++++++++++++-- 4 files changed, 58 insertions(+), 6 deletions(-) diff --git a/node/Cargo.toml b/node/Cargo.toml index ed722f1015baf..34d4304f4963e 100644 --- a/node/Cargo.toml +++ b/node/Cargo.toml @@ -74,5 +74,10 @@ version = '2.0.0-alpha.7' [build-dependencies.substrate-build-script-utils] version = '2.0.0-alpha.7' +[dependencies.evm] +default-features = false +version = '2.0.0-alpha.7' +package = 'pallet-evm' + [[bin]] name = 'node-moonbeam' diff --git a/node/src/chain_spec.rs b/node/src/chain_spec.rs index 8492b96dd18a8..c7ac4a969e713 100644 --- a/node/src/chain_spec.rs +++ b/node/src/chain_spec.rs @@ -1,13 +1,14 @@ use node_moonbeam_runtime::{ - AccountId, AuraConfig, BalancesConfig, GenesisConfig, GrandpaConfig, Signature, SudoConfig, - SystemConfig, WASM_BINARY, + AccountId, AuraConfig, BalancesConfig, EVMAccount, EVMConfig, GenesisConfig, GrandpaConfig, + Signature, SudoConfig, SystemConfig, WASM_BINARY, }; use sc_service::ChainType; use sp_consensus_aura::sr25519::AuthorityId as AuraId; -use sp_core::{sr25519, Pair, Public}; +use sp_core::{sr25519, Pair, Public, U256}; use sp_finality_grandpa::AuthorityId as GrandpaId; -use sp_runtime::traits::{IdentifyAccount, Verify}; +use sp_runtime::traits::{BlakeTwo256, IdentifyAccount, Verify}; +use evm::{ConvertAccountId, HashTruncateConvertAccountId}; // Note this is the URL for the telemetry server //const STAGING_TELEMETRY_URL: &str = "wss://telemetry.polkadot.io/submit/"; @@ -105,6 +106,10 @@ fn testnet_genesis( endowed_accounts: Vec, _enable_println: bool, ) -> GenesisConfig { + let alice_account_id = get_account_id_from_seed::("Alice"); + let alice_evm_account_id = + HashTruncateConvertAccountId::::convert_account_id(&alice_account_id); + GenesisConfig { system: Some(SystemConfig { code: WASM_BINARY.to_vec(), @@ -127,5 +132,14 @@ fn testnet_genesis( .collect(), }), sudo: Some(SudoConfig { key: root_key }), + evm: Some(EVMConfig { + accounts: vec![( + alice_evm_account_id, + EVMAccount { + nonce: 0.into(), + balance: U256::MAX, + }, + )], + }), } } diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index f89d0a051084e..4ca3326f0d200 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -121,6 +121,11 @@ version = '1.0.5' [package.metadata.docs.rs] targets = ['x86_64-unknown-linux-gnu'] +[dependencies.evm] +default-features = false +version = '2.0.0-alpha.7' +package = 'pallet-evm' + [features] default = ['std'] std = [ @@ -148,4 +153,5 @@ std = [ 'system/std', 'timestamp/std', 'transaction-payment/std', + 'evm/std', ] diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 2f478f470b6a5..1db1119b7d9d4 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -12,22 +12,25 @@ use grandpa::fg_primitives; use grandpa::AuthorityList as GrandpaAuthorityList; use sp_api::impl_runtime_apis; use sp_consensus_aura::sr25519::AuthorityId as AuraId; -use sp_core::OpaqueMetadata; +use sp_core::{OpaqueMetadata, U256}; use sp_runtime::traits::{ BlakeTwo256, Block as BlockT, ConvertInto, IdentifyAccount, IdentityLookup, Verify, }; use sp_runtime::{ create_runtime_str, generic, impl_opaque_keys, transaction_validity::{TransactionSource, TransactionValidity}, - ApplyExtrinsicResult, MultiSignature, + ApplyExtrinsicResult, ModuleId, MultiSignature, }; use sp_std::prelude::*; #[cfg(feature = "std")] use sp_version::NativeVersion; use sp_version::RuntimeVersion; +use evm::{FeeCalculator, HashTruncateConvertAccountId}; + // A few exports that help ease life for downstream crates. pub use balances::Call as BalancesCall; +pub use evm::Account as EVMAccount; pub use frame_support::{ construct_runtime, parameter_types, traits::Randomness, @@ -68,6 +71,9 @@ pub type Hash = sp_core::H256; /// Digest item type. pub type DigestItem = generic::DigestItem; +// EVM structs +pub struct FixedGasPrice; + /// 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 @@ -128,6 +134,8 @@ parameter_types! { pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75); pub const MaximumBlockLength: u32 = 5 * 1024 * 1024; pub const Version: RuntimeVersion = VERSION; + + pub const EVMModuleId: ModuleId = ModuleId(*b"py/evmpa"); } impl system::Trait for Runtime { @@ -231,6 +239,24 @@ impl sudo::Trait for Runtime { type Call = Call; } +impl FeeCalculator for FixedGasPrice { + fn min_gas_price() -> U256 { + // Gas price is always one token per gas. + 1.into() + } +} + +impl evm::Trait for Runtime { + type ModuleId = EVMModuleId; + type FeeCalculator = FixedGasPrice; + type ConvertAccountId = HashTruncateConvertAccountId; + type Currency = Balances; + type Event = Event; + type Precompiles = (); // We can use () here because paint_evm provides an + // `impl Precompiles for ()`` + // block that always returns none (line 75) +} + construct_runtime!( pub enum Runtime where Block = Block, @@ -245,6 +271,7 @@ construct_runtime!( Balances: balances::{Module, Call, Storage, Config, Event}, TransactionPayment: transaction_payment::{Module, Storage}, Sudo: sudo::{Module, Call, Config, Storage, Event}, + EVM: evm::{Module, Config, Call, Storage, Event}, } );