Skip to content

Commit c578318

Browse files
Moliholybkchrmichalkucharczyk
authored
Add chain properties to chain-spec-builder (#7368)
This PR adds support for chain properties to `chain-spec-builder`. Now properties can be specified as such: ```sh $ chain-spec-builder create -r $RUNTIME_PATH --properties tokenSymbol=DUMMY,tokenDecimals=6,isEthereum=false ``` --------- Co-authored-by: Bastian Köcher <[email protected]> Co-authored-by: Michal Kucharczyk <[email protected]>
1 parent 87ac3f2 commit c578318

File tree

4 files changed

+120
-3
lines changed

4 files changed

+120
-3
lines changed

prdoc/pr_7368.prdoc

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0
2+
# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json
3+
4+
title: "Add chain properties to chain-spec-builder"
5+
6+
doc:
7+
- audience: Node Dev
8+
description: |
9+
- Adds support for chain properties to chain-spec-builder.
10+
11+
crates:
12+
- name: staging-chain-spec-builder
13+
bump: minor

substrate/bin/utils/chain-spec-builder/src/lib.rs

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,18 @@ pub struct CreateCmd {
8383
/// errors will be reported.
8484
#[arg(long, short = 'v')]
8585
verify: bool,
86+
/// Chain properties in `KEY=VALUE` format.
87+
///
88+
/// Multiple `KEY=VALUE` entries can be specified and separated by a comma.
89+
///
90+
/// Example: `--properties tokenSymbol=UNIT,tokenDecimals=12,ss58Format=42,isEthereum=false`
91+
/// Or: `--properties tokenSymbol=UNIT --properties tokenDecimals=12 --properties ss58Format=42
92+
/// --properties=isEthereum=false`
93+
///
94+
/// The first uses comma as separation and the second passes the argument multiple times. Both
95+
/// styles can also be mixed.
96+
#[arg(long, default_value = "tokenSymbol=UNIT,tokenDecimals=12")]
97+
pub properties: Vec<String>,
8698
#[command(subcommand)]
8799
action: GenesisBuildAction,
88100

@@ -385,15 +397,44 @@ impl CreateCmd {
385397
}
386398
}
387399

388-
/// Processes `CreateCmd` and returns string represenataion of JSON version of `ChainSpec`.
400+
/// Parses chain properties passed as a comma-separated KEY=VALUE pairs.
401+
fn parse_properties(raw: &String, props: &mut sc_chain_spec::Properties) -> Result<(), String> {
402+
for pair in raw.split(',') {
403+
let mut iter = pair.splitn(2, '=');
404+
let key = iter
405+
.next()
406+
.ok_or_else(|| format!("Invalid chain property key: {pair}"))?
407+
.trim()
408+
.to_owned();
409+
let value_str = iter
410+
.next()
411+
.ok_or_else(|| format!("Invalid chain property value for key: {key}"))?
412+
.trim();
413+
414+
// Try to parse as bool, number, or fallback to String
415+
let value = match value_str.parse::<bool>() {
416+
Ok(b) => Value::Bool(b),
417+
Err(_) => match value_str.parse::<u32>() {
418+
Ok(i) => Value::Number(i.into()),
419+
Err(_) => Value::String(value_str.to_string()),
420+
},
421+
};
422+
423+
props.insert(key, value);
424+
}
425+
Ok(())
426+
}
427+
428+
/// Processes `CreateCmd` and returns string representation of JSON version of `ChainSpec`.
389429
pub fn generate_chain_spec_for_runtime(cmd: &CreateCmd) -> Result<String, String> {
390430
let code = cmd.get_runtime_code()?;
391431

392432
let chain_type = &cmd.chain_type;
393433

394434
let mut properties = sc_chain_spec::Properties::new();
395-
properties.insert("tokenSymbol".into(), "UNIT".into());
396-
properties.insert("tokenDecimals".into(), 12.into());
435+
for raw in &cmd.properties {
436+
parse_properties(raw, &mut properties)?;
437+
}
397438

398439
let builder = ChainSpec::builder(&code[..], Default::default())
399440
.with_name(&cmd.chain_name[..])
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
{
2+
"name": "Custom",
3+
"id": "custom",
4+
"chainType": "Live",
5+
"bootNodes": [],
6+
"telemetryEndpoints": null,
7+
"protocolId": null,
8+
"properties": {
9+
"tokenDecimals": 6,
10+
"tokenSymbol": "TEST",
11+
"ss58Prefix": 42,
12+
"isEthereum": false
13+
},
14+
"codeSubstitutes": {},
15+
"genesis": {
16+
"runtimeGenesis": {
17+
"code": "0x010203",
18+
"config": {
19+
"babe": {
20+
"authorities": [],
21+
"epochConfig": {
22+
"allowed_slots": "PrimaryAndSecondaryVRFSlots",
23+
"c": [
24+
1,
25+
4
26+
]
27+
}
28+
},
29+
"balances": {
30+
"balances": [],
31+
"devAccounts": null
32+
},
33+
"substrateTest": {
34+
"authorities": []
35+
},
36+
"system": {}
37+
}
38+
}
39+
}
40+
}

substrate/bin/utils/chain-spec-builder/tests/test.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,29 @@ fn test_add_code_substitute() {
234234
assert_output_eq_expected(true, SUFFIX, "tests/expected/add_code_substitute.json");
235235
}
236236

237+
#[test]
238+
fn test_create_with_properties() {
239+
const SUFFIX: &str = "11";
240+
let mut builder = get_builder(
241+
SUFFIX,
242+
vec![
243+
"create",
244+
"-r",
245+
DUMMY_PATH,
246+
"--properties",
247+
"tokenSymbol=TEST,tokenDecimals=6",
248+
"--properties",
249+
"isEthereum=false",
250+
"--properties",
251+
"ss58Prefix=42",
252+
"default",
253+
],
254+
);
255+
builder.set_create_cmd_runtime_code(substrate_test_runtime::WASM_BINARY.unwrap().into());
256+
builder.run().unwrap();
257+
assert_output_eq_expected(true, SUFFIX, "tests/expected/create_with_properties.json");
258+
}
259+
237260
#[docify::export_content]
238261
fn cmd_create_default(runtime_path: &str) -> String {
239262
bash!(

0 commit comments

Comments
 (0)