Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

parachain-omni-node binary #3597

Closed
wants to merge 19 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions substrate/client/chain-spec/src/chain_spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,19 @@ enum Genesis<G> {
RuntimeGenesis(RuntimeGenesisInner),
}

// impl debug for Genesis where we just print the variant name and drop inner value, for simplicity
impl<G> std::fmt::Debug for Genesis<G> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Genesis::Runtime(_) => write!(f, "Runtime"),
Genesis::RuntimeAndCode(_) => write!(f, "RuntimeAndCode"),
Genesis::Raw(_) => write!(f, "Raw"),
Genesis::StateRootHash(_) => write!(f, "StateRootHash"),
Genesis::RuntimeGenesis(_) => write!(f, "RuntimeGenesis"),
}
}
}

/// A configuration of a client. Does not include runtime storage initialization.
/// Note: `genesis` field is ignored due to way how the chain specification is serialized into
/// JSON file. Refer to [`ChainSpecJsonContainer`], which flattens [`ClientSpec`] and denies uknown
Expand Down
6 changes: 2 additions & 4 deletions substrate/primitives/blockchain/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,13 +168,11 @@ pub enum Error {
#[error(transparent)]
Application(#[from] Box<dyn std::error::Error + Send + Sync + 'static>),

// Should be removed/improved once
// the storage `fn`s returns typed errors.
// Should be removed/improved once the storage `fn`s returns typed errors.
#[error("Runtime code error: {0}")]
RuntimeCode(&'static str),

// Should be removed/improved once
// the storage `fn`s returns typed errors.
// Should be removed/improved once the storage `fn`s returns typed errors.
#[error("Storage error: {0}")]
Storage(String),
}
Expand Down
3 changes: 2 additions & 1 deletion substrate/utils/frame/rpc/system/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ use sp_blockchain::HeaderBackend;
use sp_core::{hexdisplay::HexDisplay, Bytes};
use sp_runtime::{legacy, traits};

pub use frame_system_rpc_runtime_api::AccountNonceApi;
// TODO: same annoying reason as per https://github.com/paritytech/polkadot-sdk/blob/fd5f9292f500652e1d4792b09fb8ac60e1268ce4/substrate/frame/src/lib.rs#L191, needs an issue and fixing.
pub use frame_system_rpc_runtime_api::{AccountNonceApi, *};

/// System RPC methods.
#[rpc(client, server)]
Expand Down
15 changes: 7 additions & 8 deletions templates/minimal/node/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ sc-rpc-api = { path = "../../../substrate/client/rpc-api" }
sc-basic-authorship = { path = "../../../substrate/client/basic-authorship" }
sc-offchain = { path = "../../../substrate/client/offchain" }
sc-client-api = { path = "../../../substrate/client/api" }
sc-chain-spec = { path = "../../../substrate/client/chain-spec" }

sp-timestamp = { path = "../../../substrate/primitives/timestamp" }
sp-keyring = { path = "../../../substrate/primitives/keyring" }
Expand All @@ -44,17 +45,15 @@ sp-blockchain = { path = "../../../substrate/primitives/blockchain" }
sp-block-builder = { path = "../../../substrate/primitives/block-builder" }
sp-io = { path = "../../../substrate/primitives/io" }
sp-runtime = { path = "../../../substrate/primitives/runtime" }
sp-version = { path = "../../../substrate/primitives/version" }
sp-transaction-pool = { path = "../../../substrate/primitives/transaction-pool" }
sp-session = { path = "../../../substrate/primitives/session" }
sp-offchain = { path = "../../../substrate/primitives/offchain" }
sp-core = { path = "../../../substrate/primitives/core" }
sp-inherents = { path = "../../../substrate/primitives/inherents" }

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

# Once the native runtime is gone, there should be little to no dependency on FRAME here, and
# certainly no dependency on the runtime.
frame = { path = "../../../substrate/frame", features = [
"experimental",
"runtime",
] }
runtime = { package = "minimal-template-runtime", path = "../runtime" }

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

Expand Down
55 changes: 0 additions & 55 deletions templates/minimal/node/src/chain_spec.rs

This file was deleted.

12 changes: 12 additions & 0 deletions templates/minimal/node/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,16 @@

use sc_cli::RunCmd;

/// The consensus algorithm to use.
#[derive(Debug, Clone)]
pub enum Consensus {
/// Manual seal, with the block time in milliseconds.
///
/// Should be provided as `manual-seal-3000` for a 3 seconds block time.
ManualSeal(u64),
/// Instant seal.
///
/// Authors a new block as soon as a transaction is received.
InstantSeal,
}

Expand All @@ -42,9 +49,14 @@ pub struct Cli {
#[command(subcommand)]
pub subcommand: Option<Subcommand>,

/// The block authoring (aka. consensus) engine to use.
#[clap(long, default_value = "manual-seal-3000")]
pub consensus: Consensus,

/// The runtime blob to use.
#[clap(long)]
pub runtime: String,

#[clap(flatten)]
pub run: RunCmd,
}
Expand Down
51 changes: 39 additions & 12 deletions templates/minimal/node/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,25 @@
// See the License for the specific language governing permissions and
// limitations under the License.

// TODO:
// - [ ] Ability to pass genesis state in a user friendly way.
// - [ ] Test this with multiple variants of minimal runtime.
// - [ ] what is happening when I run this with --execution Native?
// - [ ] Give it the polkadot runtime. Maybe even that will work?
// - [ ] Give it a parachain runtime.

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

#[cfg(feature = "try-runtime")]
use try_runtime_cli::block_building_info::timestamp_with_aura_info;
pub type ChainSpec = sc_service::GenericChainSpec<()>;

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

fn impl_version() -> String {
Expand All @@ -51,12 +56,34 @@ impl SubstrateCli for Cli {
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))?),
})
fn load_spec(&self, maybe_path: &str) -> Result<Box<dyn sc_service::ChainSpec>, String> {
// TODO: it would be good to be able to provide a chain-spec that has no code, and code is
// still read from `--runtime`. So your chain spec can be cleaner, and it is only initial
// state.
let code = std::fs::read(&self.runtime)
.map_err(|e| format!("Failed to runtime read {}: {}", &self.runtime, e))?;

Ok(Box::new(if maybe_path.is_empty() {
println!("Using development chain spec, no genesis state set.");
let mut properties = Properties::new();
properties.insert("tokenDecimals".to_string(), 0.into());
properties.insert("tokenSymbol".to_string(), "MINI".into());

// `.with_genesis_config(Default::default)` won't work, but should.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@michalkucharczyk this was my main chain-spec related issue so far, I would have expected it to work without this. Or perhaps the Default::default should do this for me.

Copy link
Contributor

@michalkucharczyk michalkucharczyk Mar 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This API is under some development. The idea is here: #1984 and some PoC: #2714.

This would help here (fetching default is trivial to add).

What I propose is to move predefined genesis configs into runtime (and call them presets), and extend GenesisBuilder runtime API to fetch them.
This would allow for functionality mentioned in #2714 (comment).

The reasoning for this is that hand-crafting chain-spec files maybe difficult as the serialization of types can be tricky to guess. Also default RuntimeGenesisConfig is typically useless (e.g. does not contains keys).

Copy link
Contributor

@michalkucharczyk michalkucharczyk Mar 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, .with_genesis_config_patch(json!({})) should do the job. (which means empty patch for default config).

let tmp = sc_chain_spec::GenesisConfigBuilderRuntimeCaller::<'_, ()>::new(&code);
let genesis = tmp.get_default_config()?;

ChainSpec::builder(code.as_ref(), Default::default())
.with_name("Development")
.with_id("dev")
.with_chain_type(ChainType::Development)
.with_properties(properties)
.with_genesis_config(genesis)
.build()
} else {
println!("Loading chain spec from {}", maybe_path);
ChainSpec::from_json_file(std::path::PathBuf::from(maybe_path))?
}))
}
}

Expand Down Expand Up @@ -114,7 +141,7 @@ pub fn run() -> sc_cli::Result<()> {
},
Some(Subcommand::ChainInfo(cmd)) => {
let runner = cli.create_runner(cmd)?;
runner.sync_run(|config| cmd.run::<runtime::interface::OpaqueBlock>(&config))
runner.sync_run(|config| cmd.run::<crate::types::OpaqueBlock>(&config))
},
None => {
let runner = cli.create_runner(&cli.run)?;
Expand Down
98 changes: 98 additions & 0 deletions templates/minimal/node/src/impl_fake_runtime_apis.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#![allow(unused_variables)]

pub struct FakeRuntime;
use crate::types::{AccountId, Header, Nonce, OpaqueBlock as Block};

sp_api::impl_runtime_apis! {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can also manually implement this stuff without this macro, but this macro already does the job easily.

// same block of code as in `minimal/runtime/src/lib.rs`, but replace all functions to be
// `todo!()`. This is only ti provide a declaration of apis to the client, code and should
// someday be removed. Since we only use the wasm executor, this is fine for now. In fact, it
// need not be "complete", it should only require the impls that this node crate needs 🤡 also,
// in general, see https://github.com/paritytech/polkadot-sdk/issues/27. In some sense, this is
// the node software fooling itself.
impl sp_api::Core<Block> for FakeRuntime {
fn version() -> sp_version::RuntimeVersion {
todo!()
}

fn execute_block(block: Block) {
todo!()
}

fn initialize_block(header: &Header) -> sp_runtime::ExtrinsicInclusionMode {
todo!()
}
}

impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for FakeRuntime {
fn validate_transaction(
_source: sp_runtime::transaction_validity::TransactionSource,
_tx: <Block as sp_runtime::traits::Block>::Extrinsic,
_hash: <Block as sp_runtime::traits::Block>::Hash,
) -> sp_runtime::transaction_validity::TransactionValidity {
todo!()
}
}

impl sp_block_builder::BlockBuilder<Block> for FakeRuntime {
fn apply_extrinsic(
extrinsic: <Block as sp_runtime::traits::Block>::Extrinsic
) -> sp_runtime::ApplyExtrinsicResult {
todo!()
}

fn finalize_block() -> <Block as sp_runtime::traits::Block>::Header {
todo!()
}

fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<<Block as sp_runtime::traits::Block>::Extrinsic> {
todo!()
}

fn check_inherents(
block: Block,
data: sp_inherents::InherentData,
) -> sp_inherents::CheckInherentsResult {
todo!()
}
}

impl sp_api::Metadata<Block> for FakeRuntime {
fn metadata() -> sp_core::OpaqueMetadata {
todo!()
}

fn metadata_at_version(version: u32) -> Option<sp_core::OpaqueMetadata> {
todo!()
}

fn metadata_versions() -> Vec<u32> {
todo!()
}
}

impl substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Nonce> for FakeRuntime {
fn account_nonce(account: AccountId) -> Nonce {
todo!();
}
}

impl sp_session::SessionKeys<Block> for FakeRuntime {
fn generate_session_keys(_seed: Option<Vec<u8>>) -> Vec<u8> {
Default::default()
}

fn decode_session_keys(
_encoded: Vec<u8>,
) -> Option<Vec<(Vec<u8>, sp_session::KeyTypeId)>> {
Default::default()
}
}

impl sp_offchain::OffchainWorkerApi<Block> for FakeRuntime {
fn offchain_worker(header: &<Block as sp_runtime::traits::Block>::Header) {
todo!();
}
}

}
3 changes: 2 additions & 1 deletion templates/minimal/node/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.

pub mod chain_spec;
pub(crate) mod cli;
pub mod impl_fake_runtime_apis;
pub mod rpc;
pub mod service;
pub mod types;
Loading
Loading