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

Commit 7a762e4

Browse files
test-runtime: GenesisBuilder runtime API impl + tests (#14310)
* test-runtime: GenesisBuilder runtime API impl + tests This PR provides implementation of `GenesisBuilder` API for `substrate-test-runtime`, can be considered as reference imiplementation for other runtimes. The `GenesisBuilder` implementation is gated by `gensis-config` feature. Tested scenarios: - default `GenesisConfig` to JSON blob, - deserialization of `GenesisConfig` from custom JSON, and storing its keys into the Storage (genesis storage creation). - creation of genesis storage using partial JSON definition, - checking if invalid/renamed JSON files causes the runtime to panic, * missing file added * client: GenesisBuilder helper added * feature renamed: genesis-config -> genesis-builder * Update Cargo.toml * Update Cargo.toml * Update Cargo.toml * Update Cargo.toml * redundant function removed * genesis builder helper: introduced RuntimeGenesisBuild * test-runtime: get rid of unused T * redundant bound removed * helper: use GenesisBuild again * tests adjusted for on_genesis * test-runtime: support for BuildGenesisConfig * helper: BuildGenesisConfig support * Update client/genesis-builder/src/lib.rs Co-authored-by: Davide Galassi <[email protected]> * Update test-utils/runtime/src/test_json/readme.md Co-authored-by: Davide Galassi <[email protected]> * Update test-utils/runtime/src/test_json/readme.md Co-authored-by: Davide Galassi <[email protected]> * Update test-utils/runtime/src/genesismap.rs Co-authored-by: Davide Galassi <[email protected]> * jsons are now human-friendly * fix * improvements * jsons fixed * helper: no_defaults added * test-runtime: no_defaults added * test-runtime: patching fn removed * helper: patching fn removed * helper: moved to frame_support * test-runtime: fixes * Cargo.lock updated * fmt + naming * test-runtime: WasmExecutor used * helper / test-runtime: struct removed * test-runtime: merge fixes * Cargo.lock + test-utils/runtime/Cargo.toml updated * doc fixed * client/rpc: test fixed (new rt api) * client/rpc-spec-v2: test fix * doc fix * test-runtime: disable-genesis-builder feature * fix * fix * ".git/.scripts/commands/fmt/fmt.sh" * test-runtime: rerun added to build script --------- Co-authored-by: Davide Galassi <[email protected]> Co-authored-by: parity-processbot <>
1 parent 0a97adf commit 7a762e4

File tree

14 files changed

+730
-24
lines changed

14 files changed

+730
-24
lines changed

Cargo.lock

+17
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

client/rpc-spec-v2/src/chain_head/tests.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ async fn follow_with_runtime() {
194194
[\"0x37e397fc7c91f5e4\",2],[\"0xd2bc9897eed08f15\",3],[\"0x40fe3ad401f8959a\",6],\
195195
[\"0xbc9d89904f5b923f\",1],[\"0xc6e9a76309f39b09\",2],[\"0xdd718d5cc53262d4\",1],\
196196
[\"0xcbca25e39f142387\",2],[\"0xf78b278be53f454c\",2],[\"0xab3c0572291feb8b\",1],\
197-
[\"0xed99c5acb25eedf5\",3]],\"transactionVersion\":1,\"stateVersion\":1}";
197+
[\"0xed99c5acb25eedf5\",3],[\"0xfbc577b9d747efd6\",1]],\"transactionVersion\":1,\"stateVersion\":1}";
198198

199199
let runtime: RuntimeVersion = serde_json::from_str(runtime_str).unwrap();
200200

client/rpc/src/state/tests.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,7 @@ async fn should_return_runtime_version() {
518518
[\"0x37e397fc7c91f5e4\",2],[\"0xd2bc9897eed08f15\",3],[\"0x40fe3ad401f8959a\",6],\
519519
[\"0xbc9d89904f5b923f\",1],[\"0xc6e9a76309f39b09\",2],[\"0xdd718d5cc53262d4\",1],\
520520
[\"0xcbca25e39f142387\",2],[\"0xf78b278be53f454c\",2],[\"0xab3c0572291feb8b\",1],\
521-
[\"0xed99c5acb25eedf5\",3]],\"transactionVersion\":1,\"stateVersion\":1}";
521+
[\"0xed99c5acb25eedf5\",3],[\"0xfbc577b9d747efd6\",1]],\"transactionVersion\":1,\"stateVersion\":1}";
522522

523523
let runtime_version = api.runtime_version(None.into()).unwrap();
524524
let serialized = serde_json::to_string(&runtime_version).unwrap();

frame/support/Cargo.toml

+3-1
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,12 @@ log = { version = "0.4.17", default-features = false }
4040
sp-core-hashing-proc-macro = { version = "9.0.0", path = "../../primitives/core/hashing/proc-macro" }
4141
k256 = { version = "0.13.0", default-features = false, features = ["ecdsa"] }
4242
environmental = { version = "1.1.4", default-features = false }
43+
sp-genesis-builder = { version = "0.1.0", default-features=false, path = "../../primitives/genesis-builder" }
44+
serde_json = { version = "1.0.85", default-features = false, features = ["alloc"] }
4345

4446
aquamarine = { version = "0.3.2" }
4547

4648
[dev-dependencies]
47-
serde_json = "1.0.85"
4849
assert_matches = "1.3.0"
4950
pretty_assertions = "1.2.1"
5051
frame-system = { version = "4.0.0-dev", path = "../system" }
@@ -72,6 +73,7 @@ std = [
7273
"frame-support-procedural/std",
7374
"log/std",
7475
"environmental/std",
76+
"sp-genesis-builder/std"
7577
]
7678
runtime-benchmarks = [
7779
"frame-system/runtime-benchmarks",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// This file is part of Substrate.
2+
3+
// Copyright (C) Parity Technologies (UK) Ltd.
4+
// SPDX-License-Identifier: Apache-2.0
5+
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
18+
//! Helper functions for implementing [`sp_genesis_builder::GenesisBuilder`] for runtimes.
19+
//!
20+
//! Provides common logic. For more info refer to [`sp_genesis_builder::GenesisBuilder`].
21+
22+
use frame_support::traits::BuildGenesisConfig;
23+
use sp_genesis_builder::Result as BuildResult;
24+
use sp_runtime::format_runtime_string;
25+
26+
/// Get the default `GenesisConfig` as a JSON blob. For more info refer to
27+
/// [`sp_genesis_builder::GenesisBuilder::create_default_config`]
28+
pub fn create_default_config<GC: BuildGenesisConfig>() -> sp_std::vec::Vec<u8> {
29+
serde_json::to_string(&GC::default())
30+
.expect("serialization to json is expected to work. qed.")
31+
.into_bytes()
32+
}
33+
34+
/// Build `GenesisConfig` from a JSON blob not using any defaults and store it in the storage. For
35+
/// more info refer to [`sp_genesis_builder::GenesisBuilder::build_config`].
36+
pub fn build_config<GC: BuildGenesisConfig>(json: sp_std::vec::Vec<u8>) -> BuildResult {
37+
let gc = serde_json::from_slice::<GC>(&json)
38+
.map_err(|e| format_runtime_string!("Invalid JSON blob: {}", e))?;
39+
<GC as BuildGenesisConfig>::build(&gc);
40+
Ok(())
41+
}

frame/support/src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -2915,3 +2915,6 @@ pub use frame_support_procedural::register_default_impl;
29152915

29162916
// Generate a macro that will enable/disable code based on `std` feature being active.
29172917
sp_core::generate_feature_enabled_macro!(std_enabled, feature = "std", $);
2918+
2919+
// Helper for implementing GenesisBuilder runtime API
2920+
pub mod genesis_builder_helper;

test-utils/runtime/Cargo.toml

+15-5
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,10 @@ publish = false
1313
targets = ["x86_64-unknown-linux-gnu"]
1414

1515
[dependencies]
16-
sp-application-crypto = { version = "23.0.0", default-features = false, path = "../../primitives/application-crypto" }
17-
sp-consensus-aura = { version = "0.10.0-dev", default-features = false, path = "../../primitives/consensus/aura" }
18-
sp-consensus-babe = { version = "0.10.0-dev", default-features = false, path = "../../primitives/consensus/babe" }
16+
sp-application-crypto = { version = "23.0.0", default-features = false, path = "../../primitives/application-crypto", features = ["serde"] }
17+
sp-consensus-aura = { version = "0.10.0-dev", default-features = false, path = "../../primitives/consensus/aura", features = ["serde"] }
18+
sp-consensus-babe = { version = "0.10.0-dev", default-features = false, path = "../../primitives/consensus/babe", features = ["serde"] }
19+
sp-genesis-builder = { version = "0.1.0-dev", default-features = false, path = "../../primitives/genesis-builder" }
1920
sp-block-builder = { version = "4.0.0-dev", default-features = false, path = "../../primitives/block-builder" }
2021
codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = ["derive"] }
2122
scale-info = { version = "2.5.0", default-features = false, features = ["derive"] }
@@ -29,14 +30,14 @@ frame-support = { version = "4.0.0-dev", default-features = false, path = "../..
2930
sp-version = { version = "22.0.0", default-features = false, path = "../../primitives/version" }
3031
sp-session = { version = "4.0.0-dev", default-features = false, path = "../../primitives/session" }
3132
sp-api = { version = "4.0.0-dev", default-features = false, path = "../../primitives/api" }
32-
sp-runtime = { version = "24.0.0", default-features = false, path = "../../primitives/runtime" }
33+
sp-runtime = { version = "24.0.0", default-features = false, path = "../../primitives/runtime", features = ["serde"] }
3334
pallet-babe = { version = "4.0.0-dev", default-features = false, path = "../../frame/babe" }
3435
pallet-balances = { version = "4.0.0-dev", default-features = false, path = "../../frame/balances" }
3536
frame-executive = { version = "4.0.0-dev", default-features = false, path = "../../frame/executive" }
3637
frame-system = { version = "4.0.0-dev", default-features = false, path = "../../frame/system" }
3738
frame-system-rpc-runtime-api = { version = "4.0.0-dev", default-features = false, path = "../../frame/system/rpc/runtime-api" }
3839
pallet-timestamp = { version = "4.0.0-dev", default-features = false, path = "../../frame/timestamp" }
39-
sp-consensus-grandpa = { version = "4.0.0-dev", default-features = false, path = "../../primitives/consensus/grandpa" }
40+
sp-consensus-grandpa = { version = "4.0.0-dev", default-features = false, path = "../../primitives/consensus/grandpa", features = ["serde"] }
4041
sp-trie = { version = "22.0.0", default-features = false, path = "../../primitives/trie" }
4142
sp-transaction-pool = { version = "4.0.0-dev", default-features = false, path = "../../primitives/transaction-pool" }
4243
trie-db = { version = "0.27.0", default-features = false }
@@ -47,14 +48,18 @@ sp-externalities = { version = "0.19.0", default-features = false, path = "../..
4748
# 3rd party
4849
array-bytes = { version = "6.1", optional = true }
4950
log = { version = "0.4.17", default-features = false }
51+
serde = { version = "1.0.163", features = ["alloc", "derive"], default-features = false }
52+
serde_json = { version = "1.0.85", default-features = false, features = ["alloc"] }
5053

5154
[dev-dependencies]
5255
futures = "0.3.21"
5356
sc-block-builder = { version = "0.10.0-dev", path = "../../client/block-builder" }
5457
sc-executor = { version = "0.10.0-dev", path = "../../client/executor" }
58+
sc-executor-common = { version = "0.10.0-dev", path = "../../client/executor/common" }
5559
sp-consensus = { version = "0.10.0-dev", path = "../../primitives/consensus/common" }
5660
substrate-test-runtime-client = { version = "2.0.0", path = "./client" }
5761
sp-tracing = { version = "10.0.0", path = "../../primitives/tracing" }
62+
json-patch = { version = "1.0.0", default-features = false }
5863

5964
[build-dependencies]
6065
substrate-wasm-builder = { version = "5.0.0-dev", path = "../../utils/wasm-builder", optional = true }
@@ -63,8 +68,10 @@ substrate-wasm-builder = { version = "5.0.0-dev", path = "../../utils/wasm-build
6368
default = [
6469
"std",
6570
]
71+
6672
std = [
6773
"array-bytes",
74+
"sp-genesis-builder/std",
6875
"sp-application-crypto/std",
6976
"sp-consensus-aura/std",
7077
"sp-consensus-babe/std",
@@ -100,3 +107,6 @@ std = [
100107
]
101108
# Special feature to disable logging
102109
disable-logging = [ "sp-api/disable-logging" ]
110+
111+
#Enabling this flag will disable GenesisBuilder API implementation in runtime.
112+
disable-genesis-builder = []

test-utils/runtime/build.rs

+15
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
// See the License for the specific language governing permissions and
1616
// limitations under the License.
1717

18+
const BUILD_NO_GENESIS_BUILDER_SUPPORT_ENV: &str = "BUILD_NO_GENESIS_BUILDER_SUPPORT";
19+
1820
fn main() {
1921
#[cfg(feature = "std")]
2022
{
@@ -29,6 +31,19 @@ fn main() {
2931
.build();
3032
}
3133

34+
#[cfg(feature = "std")]
35+
if std::env::var(BUILD_NO_GENESIS_BUILDER_SUPPORT_ENV).is_ok() {
36+
substrate_wasm_builder::WasmBuilder::new()
37+
.with_current_project()
38+
.export_heap_base()
39+
.append_to_rust_flags("-Clink-arg=-zstack-size=1048576")
40+
.set_file_name("wasm_binary_no_genesis_builder")
41+
.import_memory()
42+
.enable_feature("disable-genesis-builder")
43+
.build();
44+
}
45+
println!("cargo:rerun-if-env-changed={}", BUILD_NO_GENESIS_BUILDER_SUPPORT_ENV);
46+
3247
#[cfg(feature = "std")]
3348
{
3449
substrate_wasm_builder::WasmBuilder::new()

test-utils/runtime/src/genesismap.rs

+15-11
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,10 @@ impl Default for GenesisStorageBuilder {
7373
}
7474

7575
impl GenesisStorageBuilder {
76-
/// Creates a storage builder for genesis config. `substrage test runtime` `GenesisConfig` is
77-
/// initialized with provided `authorities`, `endowed_accounts` with given balance. Key-pairs
78-
/// from `extra_storage` will be injected into built storage. `HEAP_PAGES` key and value will
79-
/// also be placed into storage.
76+
/// Creates a storage builder for genesis config. `substrage test runtime`
77+
/// [`RuntimeGenesisConfig`] is initialized with provided `authorities`, `endowed_accounts` with
78+
/// given balance. Key-value pairs from `extra_storage` will be injected into built storage.
79+
/// `HEAP_PAGES` key and value will also be placed into storage.
8080
pub fn new(
8181
authorities: Vec<AccountId>,
8282
endowed_accounts: Vec<AccountId>,
@@ -91,7 +91,7 @@ impl GenesisStorageBuilder {
9191
}
9292
}
9393

94-
/// Override default wasm code to be placed into GenesisConfig.
94+
/// Override default wasm code to be placed into RuntimeGenesisConfig.
9595
pub fn with_wasm_code(mut self, wasm_code: &Option<Vec<u8>>) -> Self {
9696
self.wasm_code = wasm_code.clone();
9797
self
@@ -107,16 +107,16 @@ impl GenesisStorageBuilder {
107107
self
108108
}
109109

110-
/// Builds the `GenesisConfig` and returns its storage.
111-
pub fn build(self) -> Storage {
110+
/// A `RuntimeGenesisConfig` from internal configuration
111+
pub fn genesis_config(&self) -> RuntimeGenesisConfig {
112112
let authorities_sr25519: Vec<_> = self
113113
.authorities
114114
.clone()
115115
.into_iter()
116116
.map(|id| sr25519::Public::from(id))
117117
.collect();
118118

119-
let genesis_config = RuntimeGenesisConfig {
119+
RuntimeGenesisConfig {
120120
system: frame_system::GenesisConfig {
121121
code: self.wasm_code.clone().unwrap_or(wasm_binary_unwrap().to_vec()),
122122
..Default::default()
@@ -135,11 +135,15 @@ impl GenesisStorageBuilder {
135135
..Default::default()
136136
},
137137
balances: pallet_balances::GenesisConfig { balances: self.balances.clone() },
138-
};
138+
}
139+
}
139140

140-
let mut storage = genesis_config
141+
/// Builds the `RuntimeGenesisConfig` and returns its storage.
142+
pub fn build(self) -> Storage {
143+
let mut storage = self
144+
.genesis_config()
141145
.build_storage()
142-
.expect("Build storage from substrate-test-runtime GenesisConfig");
146+
.expect("Build storage from substrate-test-runtime RuntimeGenesisConfig");
143147

144148
if let Some(heap_pages) = self.heap_pages_override {
145149
storage.top.insert(well_known_keys::HEAP_PAGES.into(), heap_pages.encode());

0 commit comments

Comments
 (0)