Skip to content

Commit

Permalink
feat: FRAME umbrella crate. (paritytech#1337)
Browse files Browse the repository at this point in the history
### Original PR paritytech/substrate#14137

This PR brings in the first version of the "_`frame` umbrella crate_".
This crate is intended to serve two purposes:

1. documentation
2. easier development with frame. Ideally, we want most users to be able
to build a frame-based pallet and runtime using just `frame` (plus
`scale-codec` and `scale-info`).

The crate is not finalized and is not yet intended for external use.
Therefore, the version is set to `0.0.1-dev`, this PR is `silent`, and
the entire crate is hidden behind the `experimental` flag. The main
intention in merging it early on is to be able to iterate on it in the
rest of
[`developer-hub`](/~https://github.com/paritytech/polkadot-sdk-docs/)
efforts.

The public API of the `frame` crate is at the moment as follows: 

```
pub mod frame
pub use frame::log
pub use frame::pallet
pub mod frame::arithmetic
pub use frame::arithmetic::<<sp_arithmetic::*>>
pub use frame::arithmetic::<<sp_arithmetic::traits::*>>
pub mod frame::deps
pub use frame::deps::codec
pub use frame::deps::frame_executive
pub use frame::deps::frame_support
pub use frame::deps::frame_system
pub use frame::deps::scale_info
pub use frame::deps::sp_api
pub use frame::deps::sp_arithmetic
pub use frame::deps::sp_block_builder
pub use frame::deps::sp_consensus_aura
pub use frame::deps::sp_consensus_grandpa
pub use frame::deps::sp_core
pub use frame::deps::sp_inherents
pub use frame::deps::sp_io
pub use frame::deps::sp_offchain
pub use frame::deps::sp_runtime
pub use frame::deps::sp_std
pub use frame::deps::sp_version
pub mod frame::derive
pub use frame::derive::CloneNoBound
pub use frame::derive::Debug
pub use frame::derive::Debug
pub use frame::derive::DebugNoBound
pub use frame::derive::Decode
pub use frame::derive::Decode
pub use frame::derive::DefaultNoBound
pub use frame::derive::Encode
pub use frame::derive::Encode
pub use frame::derive::EqNoBound
pub use frame::derive::PartialEqNoBound
pub use frame::derive::RuntimeDebug
pub use frame::derive::RuntimeDebugNoBound
pub use frame::derive::TypeInfo
pub use frame::derive::TypeInfo
pub mod frame::prelude
pub use frame::prelude::<<frame_support::pallet_prelude::*>>
pub use frame::prelude::<<frame_system::pallet_prelude::*>>
pub use frame::prelude::<<sp_std::prelude::*>>
pub use frame::prelude::CloneNoBound
pub use frame::prelude::Debug
pub use frame::prelude::Debug
pub use frame::prelude::DebugNoBound
pub use frame::prelude::Decode
pub use frame::prelude::Decode
pub use frame::prelude::DefaultNoBound
pub use frame::prelude::Encode
pub use frame::prelude::Encode
pub use frame::prelude::EqNoBound
pub use frame::prelude::PartialEqNoBound
pub use frame::prelude::RuntimeDebug
pub use frame::prelude::RuntimeDebugNoBound
pub use frame::prelude::TypeInfo
pub use frame::prelude::TypeInfo
pub use frame::prelude::frame_system
pub mod frame::primitives
pub use frame::primitives::BlakeTwo256
pub use frame::primitives::H160
pub use frame::primitives::H256
pub use frame::primitives::H512
pub use frame::primitives::Hash
pub use frame::primitives::Keccak256
pub use frame::primitives::U256
pub use frame::primitives::U512
pub mod frame::runtime
pub mod frame::runtime::apis
pub use frame::runtime::apis::<<frame_system_rpc_runtime_api::*>>
pub use frame::runtime::apis::<<sp_api::*>>
pub use frame::runtime::apis::<<sp_block_builder::*>>
pub use frame::runtime::apis::<<sp_consensus_aura::*>>
pub use frame::runtime::apis::<<sp_consensus_grandpa::*>>
pub use frame::runtime::apis::<<sp_offchain::*>>
pub use frame::runtime::apis::<<sp_session::runtime_api::*>>
pub use frame::runtime::apis::<<sp_transaction_pool::runtime_api::*>>
pub use frame::runtime::apis::ApplyExtrinsicResult
pub use frame::runtime::apis::CheckInherentsResult
pub use frame::runtime::apis::InherentData
pub use frame::runtime::apis::OpaqueMetadata
pub use frame::runtime::apis::impl_runtime_apis
pub use frame::runtime::apis::sp_api
pub mod frame::runtime::prelude
pub use frame::runtime::prelude::<<frame_executive::*>>
pub use frame::runtime::prelude::ConstBool
pub use frame::runtime::prelude::ConstI128
pub use frame::runtime::prelude::ConstI16
pub use frame::runtime::prelude::ConstI32
pub use frame::runtime::prelude::ConstI64
pub use frame::runtime::prelude::ConstI8
pub use frame::runtime::prelude::ConstU128
pub use frame::runtime::prelude::ConstU16
pub use frame::runtime::prelude::ConstU32
pub use frame::runtime::prelude::ConstU64
pub use frame::runtime::prelude::ConstU8
pub use frame::runtime::prelude::NativeVersion
pub use frame::runtime::prelude::RuntimeVersion
pub use frame::runtime::prelude::construct_runtime
pub use frame::runtime::prelude::create_runtime_str
pub use frame::runtime::prelude::derive_impl
pub use frame::runtime::prelude::frame_support
pub use frame::runtime::prelude::ord_parameter_types
pub use frame::runtime::prelude::parameter_types
pub use frame::runtime::prelude::runtime_version
pub mod frame::runtime::testing_prelude
pub use frame::runtime::testing_prelude::BuildStorage
pub use frame::runtime::testing_prelude::Storage
pub mod frame::runtime::types_common
pub type frame::runtime::types_common::AccountId = <<frame::runtime::types_common::Signature as sp_runtime::traits::Verify>::Signer as sp_runtime::traits::IdentifyAccount>::AccountId
pub type frame::runtime::types_common::BlockNumber = u32
pub type frame::runtime::types_common::BlockOf<T, Extra> = sp_runtime::generic::block::Block<sp_runtime::generic::header::Header<frame::runtime::types_common::BlockNumber, sp_runtime::traits::BlakeTwo256>, sp_runtime::generic::unchecked_extrinsic::UncheckedExtrinsic<sp_runtime::multiaddress::MultiAddress<frame::runtime::types_common::AccountId, ()>, <T as frame_system::pallet::Config>::RuntimeCall, frame::runtime::types_common::Signature, Extra>>
pub type frame::runtime::types_common::OpaqueBlock = sp_runtime::generic::block::Block<sp_runtime::generic::header::Header<frame::runtime::types_common::BlockNumber, sp_runtime::traits::BlakeTwo256>, sp_runtime::OpaqueExtrinsic>
pub type frame::runtime::types_common::Signature = sp_runtime::MultiSignature
pub type frame::runtime::types_common::SystemSignedExtensionsOf<T> = (frame_system::extensions::check_non_zero_sender::CheckNonZeroSender<T>, frame_system::extensions::check_spec_version::CheckSpecVersion<T>, frame_system::extensions::check_tx_version::CheckTxVersion<T>, frame_system::extensions::check_genesis::CheckGenesis<T>, frame_system::extensions::check_mortality::CheckMortality<T>, frame_system::extensions::check_nonce::CheckNonce<T>, frame_system::extensions::check_weight::CheckWeight<T>)
pub mod frame::testing_prelude
pub use frame::testing_prelude::<<frame_executive::*>>
pub use frame::testing_prelude::<<frame_system::mocking::*>>
pub use frame::testing_prelude::BuildStorage
pub use frame::testing_prelude::ConstBool
pub use frame::testing_prelude::ConstI128
pub use frame::testing_prelude::ConstI16
pub use frame::testing_prelude::ConstI32
pub use frame::testing_prelude::ConstI64
pub use frame::testing_prelude::ConstI8
pub use frame::testing_prelude::ConstU128
pub use frame::testing_prelude::ConstU16
pub use frame::testing_prelude::ConstU32
pub use frame::testing_prelude::ConstU64
pub use frame::testing_prelude::ConstU8
pub use frame::testing_prelude::NativeVersion
pub use frame::testing_prelude::RuntimeVersion
pub use frame::testing_prelude::Storage
pub use frame::testing_prelude::TestState
pub use frame::testing_prelude::assert_err
pub use frame::testing_prelude::assert_err_ignore_postinfo
pub use frame::testing_prelude::assert_error_encoded_size
pub use frame::testing_prelude::assert_noop
pub use frame::testing_prelude::assert_ok
pub use frame::testing_prelude::assert_storage_noop
pub use frame::testing_prelude::construct_runtime
pub use frame::testing_prelude::create_runtime_str
pub use frame::testing_prelude::derive_impl
pub use frame::testing_prelude::frame_support
pub use frame::testing_prelude::frame_system
pub use frame::testing_prelude::if_std
pub use frame::testing_prelude::ord_parameter_types
pub use frame::testing_prelude::parameter_types
pub use frame::testing_prelude::runtime_version
pub use frame::testing_prelude::storage_alias
pub mod frame::traits
pub use frame::traits::<<frame_support::traits::*>>
pub use frame::traits::<<sp_runtime::traits::*>>
```

---

The road to full stabilization is

- [ ] paritytech#127
- [ ] have a more intentional version bump, as opposed to the current bi
weekly force-major-bump
- [ ] revise the internal API of `frame`, especially what goes into the
`prelude`s.
- [ ] migrate all internal pallets and runtime to use `frame`

---------

Co-authored-by: kianenigma <kian@parity.io>
Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>
Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>
Co-authored-by: Francisco Aguirre <franciscoaguirreperez@gmail.com>
  • Loading branch information
5 people authored Oct 27, 2023
1 parent f993c11 commit ba4c3b5
Show file tree
Hide file tree
Showing 43 changed files with 1,862 additions and 179 deletions.
2 changes: 1 addition & 1 deletion substrate/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ version = "1.0.0"

# The dependencies are only needed for docs.
[dependencies]
aquamarine = "0.3.2"
simple-mermaid = { git = "/~https://github.com/kianenigma/simple-mermaid.git", rev = "e48b187bcfd5cc75111acd9d241f1bd36604344b" }

subkey = { path = "bin/utils/subkey" }
chain-spec-builder = { path = "bin/utils/chain-spec-builder" }
Expand Down
56 changes: 56 additions & 0 deletions substrate/bin/minimal/node/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
[package]
name = "minimal-node"
version = "4.0.0-dev"
description = "A fresh FRAME-based Substrate node, ready for hacking."
authors = ["Substrate DevHub </~https://github.com/substrate-developer-hub>"]
homepage = "https://substrate.io/"
edition = "2021"
license = "MIT-0"
publish = false
repository = "/~https://github.com/substrate-developer-hub/substrate-node-template/"
build = "build.rs"

[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

[[bin]]
name = "minimal-node"

[dependencies]
clap = { version = "4.0.9", features = ["derive"] }
futures = { version = "0.3.21", features = ["thread-pool"] }
futures-timer = "3.0.1"
jsonrpsee = { version = "0.16.2", features = ["server"] }

sc-cli = { path = "../../../client/cli" }
sc-executor = { path = "../../../client/executor" }
sc-network = { path = "../../../client/network" }
sc-service = { path = "../../../client/service" }
sc-telemetry = { path = "../../../client/telemetry" }
sc-transaction-pool = { path = "../../../client/transaction-pool" }
sc-transaction-pool-api = { path = "../../../client/transaction-pool/api" }
sc-consensus = { path = "../../../client/consensus/common" }
sc-consensus-manual-seal = { path = "../../../client/consensus/manual-seal" }
sc-rpc-api = { path = "../../../client/rpc-api" }
sc-basic-authorship = { path = "../../../client/basic-authorship" }
sc-offchain = { path = "../../../client/offchain" }
sc-client-api = { path = "../../../client/api" }

sp-timestamp = { path = "../../../primitives/timestamp" }
sp-keyring = { path = "../../../primitives/keyring" }
sp-api = { path = "../../../primitives/api" }
sp-blockchain = { path = "../../../primitives/blockchain" }
sp-block-builder = { path = "../../../primitives/block-builder" }
sp-io = { path = "../../../primitives/io" }
sp-runtime = { path = "../../../primitives/runtime" }

substrate-frame-rpc-system = { path = "../../../utils/frame/rpc/system" }

frame = { path = "../../../frame", features = ["runtime", "experimental"] }
runtime = { package = "minimal-runtime", path = "../runtime" }

[build-dependencies]
substrate-build-script-utils = { version = "3.0.0", path = "../../../utils/build-script-utils" }

[features]
default = []
23 changes: 23 additions & 0 deletions substrate/bin/minimal/node/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// This file is part of Substrate.

// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use substrate_build_script_utils::{generate_cargo_keys, rerun_if_git_head_changed};

fn main() {
generate_cargo_keys();
rerun_if_git_head_changed();
}
66 changes: 66 additions & 0 deletions substrate/bin/minimal/node/src/chain_spec.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// This file is part of Substrate.

// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use runtime::{BalancesConfig, RuntimeGenesisConfig, SudoConfig, SystemConfig, WASM_BINARY};
use sc_service::{ChainType, Properties};
use sp_keyring::AccountKeyring;

/// This is a specialization of the general Substrate ChainSpec type.
pub type ChainSpec = sc_service::GenericChainSpec<RuntimeGenesisConfig>;

fn props() -> Properties {
let mut properties = Properties::new();
properties.insert("tokenDecimals".to_string(), 0.into());
properties.insert("tokenSymbol".to_string(), "MINI".into());
properties
}

pub fn development_config() -> Result<ChainSpec, String> {
let wasm_binary = WASM_BINARY.ok_or_else(|| "Development wasm not available".to_string())?;
Ok(ChainSpec::from_genesis(
"Development",
"dev",
ChainType::Development,
move || testnet_genesis(wasm_binary),
vec![],
None,
None,
None,
Some(props()),
None,
))
}

/// Configure initial storage state for FRAME pallets.
fn testnet_genesis(wasm_binary: &[u8]) -> RuntimeGenesisConfig {
use frame::traits::Get;
use runtime::interface::{Balance, MinimumBalance};
let endowment = <MinimumBalance as Get<Balance>>::get().max(1) * 1000;
let balances = AccountKeyring::iter()
.map(|a| (a.to_account_id(), endowment))
.collect::<Vec<_>>();
RuntimeGenesisConfig {
system: SystemConfig {
// Add Wasm runtime to storage.
code: wasm_binary.to_vec(),
_config: Default::default(),
},
balances: BalancesConfig { balances },
sudo: SudoConfig { key: Some(AccountKeyring::Alice.to_account_id()) },
..Default::default()
}
}
81 changes: 81 additions & 0 deletions substrate/bin/minimal/node/src/cli.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// This file is part of Substrate.

// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use sc_cli::RunCmd;

#[derive(Debug, Clone)]
pub enum Consensus {
ManualSeal(u64),
InstantSeal,
}

impl std::str::FromStr for Consensus {
type Err = String;

fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(if s == "instant-seal" {
Consensus::InstantSeal
} else if let Some(block_time) = s.strip_prefix("manual-seal-") {
Consensus::ManualSeal(block_time.parse().map_err(|_| "invalid block time")?)
} else {
return Err("incorrect consensus identifier".into())
})
}
}

#[derive(Debug, clap::Parser)]
pub struct Cli {
#[command(subcommand)]
pub subcommand: Option<Subcommand>,

#[clap(long, default_value = "manual-seal-3000")]
pub consensus: Consensus,

#[clap(flatten)]
pub run: RunCmd,
}

#[derive(Debug, clap::Subcommand)]
pub enum Subcommand {
/// Key management cli utilities
#[command(subcommand)]
Key(sc_cli::KeySubcommand),

/// Build a chain specification.
BuildSpec(sc_cli::BuildSpecCmd),

/// Validate blocks.
CheckBlock(sc_cli::CheckBlockCmd),

/// Export blocks.
ExportBlocks(sc_cli::ExportBlocksCmd),

/// Export the state of a given block into a chain spec.
ExportState(sc_cli::ExportStateCmd),

/// Import blocks.
ImportBlocks(sc_cli::ImportBlocksCmd),

/// Remove the whole chain.
PurgeChain(sc_cli::PurgeChainCmd),

/// Revert the chain to a previous state.
Revert(sc_cli::RevertCmd),

/// Db meta columns information.
ChainInfo(sc_cli::ChainInfoCmd),
}
126 changes: 126 additions & 0 deletions substrate/bin/minimal/node/src/command.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
// This file is part of Substrate.

// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use crate::{
chain_spec,
cli::{Cli, Subcommand},
service,
};
use sc_cli::SubstrateCli;
use sc_service::PartialComponents;

#[cfg(feature = "try-runtime")]
use try_runtime_cli::block_building_info::timestamp_with_aura_info;

impl SubstrateCli for Cli {
fn impl_name() -> String {
"Substrate Node".into()
}

fn impl_version() -> String {
env!("SUBSTRATE_CLI_IMPL_VERSION").into()
}

fn description() -> String {
env!("CARGO_PKG_DESCRIPTION").into()
}

fn author() -> String {
env!("CARGO_PKG_AUTHORS").into()
}

fn support_url() -> String {
"support.anonymous.an".into()
}

fn copyright_start_year() -> i32 {
2017
}

fn load_spec(&self, id: &str) -> Result<Box<dyn sc_service::ChainSpec>, String> {
Ok(match id {
"dev" => Box::new(chain_spec::development_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::Key(cmd)) => cmd.run(&cli),
Some(Subcommand::BuildSpec(cmd)) => {
let runner = cli.create_runner(cmd)?;
runner.sync_run(|config| cmd.run(config.chain_spec, config.network))
},
Some(Subcommand::CheckBlock(cmd)) => {
let runner = cli.create_runner(cmd)?;
runner.async_run(|config| {
let PartialComponents { client, task_manager, import_queue, .. } =
service::new_partial(&config)?;
Ok((cmd.run(client, import_queue), task_manager))
})
},
Some(Subcommand::ExportBlocks(cmd)) => {
let runner = cli.create_runner(cmd)?;
runner.async_run(|config| {
let PartialComponents { client, task_manager, .. } = service::new_partial(&config)?;
Ok((cmd.run(client, config.database), task_manager))
})
},
Some(Subcommand::ExportState(cmd)) => {
let runner = cli.create_runner(cmd)?;
runner.async_run(|config| {
let PartialComponents { client, task_manager, .. } = service::new_partial(&config)?;
Ok((cmd.run(client, config.chain_spec), task_manager))
})
},
Some(Subcommand::ImportBlocks(cmd)) => {
let runner = cli.create_runner(cmd)?;
runner.async_run(|config| {
let PartialComponents { client, task_manager, import_queue, .. } =
service::new_partial(&config)?;
Ok((cmd.run(client, import_queue), task_manager))
})
},
Some(Subcommand::PurgeChain(cmd)) => {
let runner = cli.create_runner(cmd)?;
runner.sync_run(|config| cmd.run(config.database))
},
Some(Subcommand::Revert(cmd)) => {
let runner = cli.create_runner(cmd)?;
runner.async_run(|config| {
let PartialComponents { client, task_manager, backend, .. } =
service::new_partial(&config)?;
Ok((cmd.run(client, backend, None), task_manager))
})
},
Some(Subcommand::ChainInfo(cmd)) => {
let runner = cli.create_runner(cmd)?;
runner.sync_run(|config| cmd.run::<runtime::interface::OpaqueBlock>(&config))
},
None => {
let runner = cli.create_runner(&cli.run)?;
runner.run_node_until_exit(|config| async move {
service::new_full(config, cli.consensus).map_err(sc_cli::Error::Service)
})
},
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

pub mod deps {
pub use frame_support;
pub use frame_system;
}
pub mod chain_spec;
pub(crate) mod cli;
pub mod rpc;
pub mod service;
Loading

0 comments on commit ba4c3b5

Please sign in to comment.