Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

WIP removing native runtime #10872

Closed
wants to merge 15 commits into from
24 changes: 6 additions & 18 deletions Cargo.lock

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

6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ members = [
"bin/node/rpc",
"bin/node/runtime",
"bin/node/testing",
"bin/utils/chain-spec-builder",
"bin/utils/subkey",
"client/api",
"client/authority-discovery",
Expand Down Expand Up @@ -276,8 +275,8 @@ yamux = { opt-level = 3 }
zeroize = { opt-level = 3 }

[profile.release]
# Substrate runtime requires unwinding.
panic = "unwind"
panic = "abort"
Copy link
Member Author

Choose a reason for hiding this comment

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

@pepyakin Do we need panic = "unwind" for wasmtime?
Otherwise, with no native runtime, we can switch to panic = "abort" and gain better performance and significantly reduced binary size.

Copy link
Contributor

Choose a reason for hiding this comment

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

I assume you mean whether traps generated by wasm code in wasmtime require unwind, and the answer is no, it works via a setjmp/longjmp like approach.

However, I think we should do this as a follow-up. The reason is, this requires some research to proof that we do not rely on this property somewhere else, because it was already there. I personally cannot recall any but it's better be safe than sorry.

Copy link
Contributor

Choose a reason for hiding this comment

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

incremental = true

[profile.production]
inherits = "release"
Expand All @@ -288,3 +287,4 @@ inherits = "release"
lto = "fat"
# https://doc.rust-lang.org/rustc/codegen-options/index.html#codegen-units
codegen-units = 1
incremental = false
6 changes: 4 additions & 2 deletions bin/node-template/node/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,13 @@ frame-benchmarking = { version = "4.0.0-dev", path = "../../../frame/benchmarkin
frame-benchmarking-cli = { version = "4.0.0-dev", path = "../../../utils/frame/benchmarking-cli" }

# Local Dependencies
node-template-runtime = { version = "4.0.0-dev", path = "../runtime" }
#node-template-runtime = { version = "4.0.0-dev", path = "../runtime" }

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

[features]
default = []
runtime-benchmarks = ["node-template-runtime/runtime-benchmarks"]
runtime-benchmarks = []
#runtime-benchmarks = ["node-template-runtime/runtime-benchmarks"]
13 changes: 13 additions & 0 deletions bin/node-template/node/build.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
use substrate_build_script_utils::{generate_cargo_keys, rerun_if_git_head_changed};
use substrate_wasm_builder::WasmBuilder;

fn main() {
build_runtime();
generate_cargo_keys();

rerun_if_git_head_changed();
}

fn build_runtime() {
let mut path = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"));
path.push("../runtime/Cargo.toml");
WasmBuilder::new()
.with_project(path.canonicalize().unwrap()).unwrap()
.export_heap_base()
.import_memory()
.build()
}

147 changes: 20 additions & 127 deletions bin/node-template/node/src/chain_spec.rs
Original file line number Diff line number Diff line change
@@ -1,156 +1,49 @@
use node_template_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};

// 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<GenesisConfig>;

/// Generate a crypto pair from seed.
pub fn get_from_seed<TPublic: Public>(seed: &str) -> <TPublic::Pair as Pair>::Public {
TPublic::Pair::from_string(&format!("//{}", seed), None)
.expect("static values are valid; qed")
.public()
}

type AccountPublic = <Signature as Verify>::Signer;

/// Generate an account ID from seed.
pub fn get_account_id_from_seed<TPublic: Public>(seed: &str) -> AccountId
where
AccountPublic: From<<TPublic::Pair as Pair>::Public>,
{
AccountPublic::from(get_from_seed::<TPublic>(seed)).into_account()
mod runtime {
include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
/// Wasm binary unwrapped. If built with `SKIP_WASM_BUILD`, the function panics.
pub fn wasm_binary_unwrap() -> &'static [u8] {
WASM_BINARY.expect(
"Development wasm binary is not available. This means the client is built with \
`SKIP_WASM_BUILD` flag and it is only usable for production chains. Please rebuild with \
the flag disabled.",
)
}
}

/// Generate an Aura authority key.
pub fn authority_keys_from_seed(s: &str) -> (AuraId, GrandpaId) {
(get_from_seed::<AuraId>(s), get_from_seed::<GrandpaId>(s))
}
/// Specialized `ChainSpec`. This is a specialization of the general Substrate ChainSpec type.
pub type ChainSpec = sc_service::GenericChainSpec<()>;

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(
// Name
Ok(ChainSpec::from_runtime(
"Development",
// ID
"dev",
ChainType::Development,
move || {
testnet_genesis(
wasm_binary,
// Initial PoA authorities
vec![authority_keys_from_seed("Alice")],
// Sudo account
get_account_id_from_seed::<sr25519::Public>("Alice"),
// Pre-funded accounts
vec![
get_account_id_from_seed::<sr25519::Public>("Alice"),
get_account_id_from_seed::<sr25519::Public>("Bob"),
get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
],
true,
)
},
// Bootnodes
runtime::wasm_binary_unwrap(),
"Genesis_build_dev",
vec![],
// Telemetry
None,
// Protocol ID
None,
None,
// Properties
None,
// Extensions
None,
Default::default(),
))
}

pub fn local_testnet_config() -> Result<ChainSpec, String> {
let wasm_binary = WASM_BINARY.ok_or_else(|| "Development wasm not available".to_string())?;

Ok(ChainSpec::from_genesis(
// Name
Ok(ChainSpec::from_runtime(
"Local Testnet",
// ID
"local_testnet",
ChainType::Local,
move || {
testnet_genesis(
wasm_binary,
// Initial PoA authorities
vec![authority_keys_from_seed("Alice"), authority_keys_from_seed("Bob")],
// Sudo account
get_account_id_from_seed::<sr25519::Public>("Alice"),
// Pre-funded accounts
vec![
get_account_id_from_seed::<sr25519::Public>("Alice"),
get_account_id_from_seed::<sr25519::Public>("Bob"),
get_account_id_from_seed::<sr25519::Public>("Charlie"),
get_account_id_from_seed::<sr25519::Public>("Dave"),
get_account_id_from_seed::<sr25519::Public>("Eve"),
get_account_id_from_seed::<sr25519::Public>("Ferdie"),
get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),
get_account_id_from_seed::<sr25519::Public>("Dave//stash"),
get_account_id_from_seed::<sr25519::Public>("Eve//stash"),
get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),
],
true,
)
},
// Bootnodes
runtime::wasm_binary_unwrap(),
"Genesis_build_genesis",
vec![],
// Telemetry
None,
// Protocol ID
None,
// Properties
None,
None,
// Extensions
None,
Default::default(),
))
}

/// Configure initial storage state for FRAME modules.
fn testnet_genesis(
wasm_binary: &[u8],
initial_authorities: Vec<(AuraId, GrandpaId)>,
root_key: AccountId,
endowed_accounts: Vec<AccountId>,
_enable_println: bool,
) -> GenesisConfig {
GenesisConfig {
system: SystemConfig {
// Add Wasm runtime to storage.
code: wasm_binary.to_vec(),
},
balances: BalancesConfig {
// Configure endowed accounts with initial balance of 1 << 60.
balances: endowed_accounts.iter().cloned().map(|k| (k, 1 << 60)).collect(),
},
aura: AuraConfig {
authorities: initial_authorities.iter().map(|x| (x.0.clone())).collect(),
},
grandpa: GrandpaConfig {
authorities: initial_authorities.iter().map(|x| (x.1.clone(), 1)).collect(),
},
sudo: SudoConfig {
// Assign network admin rights.
key: Some(root_key),
},
transaction_payment: Default::default(),
}
}
10 changes: 3 additions & 7 deletions bin/node-template/node/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use crate::{
cli::{Cli, Subcommand},
service,
};
use node_template_runtime::Block;
use sc_cli::{ChainSpec, RuntimeVersion, SubstrateCli};
use service::Block;
use sc_cli::{SubstrateCli};
use sc_service::PartialComponents;

impl SubstrateCli for Cli {
Expand Down Expand Up @@ -40,10 +40,6 @@ impl SubstrateCli for Cli {
Box::new(chain_spec::ChainSpec::from_json_file(std::path::PathBuf::from(path))?),
})
}

fn native_runtime_version(_: &Box<dyn ChainSpec>) -> &'static RuntimeVersion {
&node_template_runtime::VERSION
}
}

/// Parse and run command line arguments
Expand Down Expand Up @@ -102,7 +98,7 @@ pub fn run() -> sc_cli::Result<()> {
if cfg!(feature = "runtime-benchmarks") {
let runner = cli.create_runner(cmd)?;

runner.sync_run(|config| cmd.run::<Block, service::ExecutorDispatch>(config))
runner.sync_run(|config| cmd.run::<Block>(config))
} else {
Err("Benchmarking wasn't enabled when building the node. You can enable it with \
`--features runtime-benchmarks`."
Expand Down
11 changes: 4 additions & 7 deletions bin/node-template/node/src/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@

use std::sync::Arc;

use node_template_runtime::{opaque::Block, AccountId, Balance, Index};
use crate::service::{Hash, Block, AccountId, Index, Balance};
pub use sc_rpc_api::DenyUnsafe;
use sc_transaction_pool_api::TransactionPool;
use sp_api::ProvideRuntimeApi;
use sp_block_builder::BlockBuilder;
use sp_blockchain::{Error as BlockChainError, HeaderBackend, HeaderMetadata};
use pallet_transaction_payment_rpc::TransactionPaymentRuntimeDispatchInfo;

/// Full client dependencies.
pub struct FullDeps<C, P> {
Expand All @@ -30,9 +30,6 @@ where
C: ProvideRuntimeApi<Block>,
C: HeaderBackend<Block> + HeaderMetadata<Block, Error = BlockChainError> + 'static,
C: Send + Sync + 'static,
C::Api: substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>,
C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi<Block, Balance>,
C::Api: BlockBuilder<Block>,
P: TransactionPool + 'static,
{
use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApi};
Expand All @@ -41,9 +38,9 @@ where
let mut io = jsonrpc_core::IoHandler::default();
let FullDeps { client, pool, deny_unsafe } = deps;

io.extend_with(SystemApi::to_delegate(FullSystem::new(client.clone(), pool, deny_unsafe)));
io.extend_with(SystemApi::<Hash, AccountId, Index>::to_delegate(FullSystem::new(client.clone(), pool, deny_unsafe)));

io.extend_with(TransactionPaymentApi::to_delegate(TransactionPayment::new(client.clone())));
io.extend_with(TransactionPaymentApi::<_, TransactionPaymentRuntimeDispatchInfo<Balance>>::to_delegate(TransactionPayment::new(client.clone())));

// Extend this RPC with a custom API by using the following syntax.
// `YourRpcStruct` should have a reference to a client, which is needed
Expand Down
Loading