Add Statemint Genesis Values (#817) (#905)

* Add Statemint Genesis Values (#817)

* add some docs to genesis scripts

* move statemint test chainspec

* add initial (draft) version of statemint chain spec

* adjust genesis value script

* add Statemint genesis Aura keys

* add bootnodes to statemint-genesis spec

* Add checks, debug and doc (#790)

* Add checks, debug and doc

* Update scripts/generate_genesis_value.sh

Co-authored-by: Alexander Popiak <alexander.popiak@parity.io>

* Update scripts/generate_genesis_value.sh

Co-authored-by: Alexander Popiak <alexander.popiak@parity.io>

Co-authored-by: Alexander Popiak <alexander.popiak@parity.io>

* default to official shell rpc endpoint for genesis values

* remove statemint test chain spec

* add Statemint chain spec and genesis values

* sort statemint genesis values

* some script docs adjustments

Co-authored-by: Chevdor <chevdor@users.noreply.github.com>

* cargo fmt

Co-authored-by: Alexander Popiak <alexander.popiak@parity.io>
Co-authored-by: Chevdor <chevdor@users.noreply.github.com>
This commit is contained in:
Squirrel
2022-01-19 10:43:46 +00:00
committed by GitHub
parent 9c4aa3b21f
commit 7ce3fe4e0d
9 changed files with 275 additions and 60 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+59
View File
@@ -355,6 +355,65 @@ pub fn statemint_local_config() -> StatemintChainSpec {
)
}
// Not used for syncing, but just to determine the genesis values set for the upgrade from shell.
pub fn statemint_config() -> StatemintChainSpec {
let mut properties = sc_chain_spec::Properties::new();
properties.insert("tokenSymbol".into(), "DOT".into());
properties.insert("tokenDecimals".into(), 10.into());
StatemintChainSpec::from_genesis(
// Name
"Statemint",
// ID
"statemint",
ChainType::Live,
move || {
statemint_genesis(
// initial collators.
vec![
(
hex!("4c3d674d2a01060f0ded218e5dcc6f90c1726f43df79885eb3e22d97a20d5421")
.into(),
hex!("4c3d674d2a01060f0ded218e5dcc6f90c1726f43df79885eb3e22d97a20d5421")
.unchecked_into(),
),
(
hex!("c7d7d38d16bc23c6321152c50306212dc22c0efc04a2e52b5cccfc31ab3d7811")
.into(),
hex!("c7d7d38d16bc23c6321152c50306212dc22c0efc04a2e52b5cccfc31ab3d7811")
.unchecked_into(),
),
(
hex!("c5c07ba203d7375675f5c1ebe70f0a5bb729ae57b48bcc877fcc2ab21309b762")
.into(),
hex!("c5c07ba203d7375675f5c1ebe70f0a5bb729ae57b48bcc877fcc2ab21309b762")
.unchecked_into(),
),
(
hex!("0b2d0013fb974794bd7aa452465b567d48ef70373fe231a637c1fb7c547e85b3")
.into(),
hex!("0b2d0013fb974794bd7aa452465b567d48ef70373fe231a637c1fb7c547e85b3")
.unchecked_into(),
),
],
vec![],
1000u32.into(),
)
},
vec![
"/ip4/34.65.251.121/tcp/30334/p2p/12D3KooWG3GrM6XKMM4gp3cvemdwUvu96ziYoJmqmetLZBXE8bSa".parse().unwrap(),
"/ip4/34.65.35.228/tcp/30334/p2p/12D3KooWMRyTLrCEPcAQD6c4EnudL3vVzg9zji3whvsMYPUYevpq".parse().unwrap(),
"/ip4/34.83.247.146/tcp/30334/p2p/12D3KooWE4jFh5FpJDkWVZhnWtFnbSqRhdjvC7Dp9b8b3FTuubQC".parse().unwrap(),
"/ip4/104.199.117.230/tcp/30334/p2p/12D3KooWG9R8pVXKumVo2rdkeVD4j5PVhRTqmYgLHY3a4yPYgLqM".parse().unwrap(),
],
None,
None,
None,
Some(properties),
Extensions { relay_chain: "polkadot".into(), para_id: 1000 },
)
}
fn statemint_genesis(
invulnerables: Vec<(AccountId, AuraId)>,
endowed_accounts: Vec<AccountId>,
+9
View File
@@ -97,9 +97,17 @@ fn load_spec(id: &str) -> std::result::Result<Box<dyn sc_service::ChainSpec>, St
&include_bytes!("../res/track.json")[..],
)?),
"shell" => Box::new(chain_spec::get_shell_chain_spec()),
// -- Statemint
"seedling" => Box::new(chain_spec::get_seedling_chain_spec()),
"statemint-dev" => Box::new(chain_spec::statemint_development_config()),
"statemint-local" => Box::new(chain_spec::statemint_local_config()),
// the chain spec as used for generating the upgrade genesis values
"statemint-genesis" => Box::new(chain_spec::statemint_config()),
// the shell-based chain spec as used for syncing
"statemint" => Box::new(chain_spec::ChainSpec::from_json_bytes(
&include_bytes!("../res/statemint.json")[..],
)?),
// -- Statemine
"statemine-dev" => Box::new(chain_spec::statemine_development_config()),
"statemine-local" => Box::new(chain_spec::statemine_local_config()),
// the chain spec as used for generating the upgrade genesis values
@@ -108,6 +116,7 @@ fn load_spec(id: &str) -> std::result::Result<Box<dyn sc_service::ChainSpec>, St
"statemine" => Box::new(chain_spec::ChainSpec::from_json_bytes(
&include_bytes!("../res/statemine.json")[..],
)?),
// -- Westmint
"westmint-dev" => Box::new(chain_spec::westmint_development_config()),
"westmint-local" => Box::new(chain_spec::westmint_local_config()),
// the chain spec as used for generating the upgrade genesis values
+63 -5
View File
@@ -1,22 +1,80 @@
#!/usr/bin/env bash
# Call from the root of the repo as:
# ./scripts/generate_genesis_value.sh <chain-id> [rpc endpoint]
usage() {
echo Usage:
echo "$0 <chain-id>"
echo "$0 <chain-id> [rpc endpoint]"
exit 1
}
chain_spec_summary() {
if [ -f $chain_spec ]; then
echo -e "️ Using chain specs from" $chain_spec
echo -e " - name :" $(jq -r .name $chain_spec)
echo -e " - id :" $(jq -r .id $chain_spec)
echo -e " - type :" $(jq -r .chainType $chain_spec)
echo -e " - decimals :" $(jq -r .properties.tokenDecimals $chain_spec)
echo -e " - symbol :" $(jq -r .properties.tokenSymbol $chain_spec)
echo -e " - relay_chain :" $(jq -r .relay_chain $chain_spec)
echo -e " - para_id :" $(jq -r .para_id $chain_spec)
echo -e " - bootNodes :" $(jq '.bootNodes | length' $chain_spec)
echo
else
echo "❌ Chain specs not found from" $chain_spec
exit 1
fi
}
check_collator() {
BIN=target/release/polkadot-collator
if [ -f $BIN ]; then
echo "✅ Collator binary found:"
$BIN --version
else
echo "❌ Collator binary not found, exiting"
exit 1
fi
}
set -e
chain_id=$1
rpc_endpoint=$2
work_dir="polkadot-parachains/res"
chain_spec=$work_dir/$chain_id.json
chain_values=$work_dir/${chain_id}_values.json
chain_values_scale=$work_dir/${chain_id}_values.scale
[ -z "$chain_id" ] && usage
chain_spec_summary
pushd generate_genesis_values
if [ "$rpc_endpoint" == "" ]; then
# default connecting to the official rpc
rpc_endpoint='wss://statemint-shell.polkadot.io'
fi
if [[ "$rpc_endpoint" =~ "localhost" ]]; then
check_collator
echo -e "Make sure you have a collator running with the correct version at $rpc_endpoint."
echo -e "If you don't, NOW is the time to start it with:"
echo -e "target/release/polkadot-collator --chain polkadot-parachains/res/shell-statemint.json --tmp\n"
read -p "You can abort with CTRL+C if this is not correct, otherwise press ENTER "
fi
echo "Generating genesis values..."
pushd scripts/generate_genesis_values
yarn
popd
node generate_genesis_values ../polkadot-parachains/res/$chain_id.json ../polkadot-parachains/res/${chain_id}_genesis_values.json
node scripts/generate_genesis_values $chain_spec $chain_values
pushd scale_encode_genesis
echo "Scale encoding..."
pushd scripts/scale_encode_genesis
yarn
popd
node scale_encode_genesis ../polkadot-parachains/res/${chain_id}_genesis_values.json ${chain_id}_genesis_values.txt
node scripts/scale_encode_genesis $chain_values $chain_values_scale $rpc_endpoint
ls -al polkadot-parachains/res/${chain_id}_value*.*
+5
View File
@@ -2,6 +2,10 @@ const fs = require("fs");
const { exit } = require("process");
const { xxhashAsHex } = require("@polkadot/util-crypto");
// Utility script scraping a chain spec for the genesis keys and values and writing them out as a
// json array of pairs. Filters the keys for anything already present in a shell runtime and sorts
// the output for reproducibility.
if (!process.argv[2] || !process.argv[3]) {
console.log("usage: node generate_keys <input chainspec> <output json>");
exit();
@@ -49,6 +53,7 @@ fs.readFile(input, "utf8", (err, data) => {
Object.entries(spec.genesis.raw.top).filter(
([key, value]) => !startsWith(key, filter_prefixes)
);
genesis.sort();
fs.writeFileSync(output, JSON.stringify(genesis));
});
+34 -20
View File
@@ -1,10 +1,15 @@
const fs = require("fs");
const { exit } = require("process");
const {WsProvider, ApiPromise} = require("@polkadot/api");
const { WsProvider, ApiPromise } = require("@polkadot/api");
const util = require("@polkadot/util");
async function connect(port, types) {
const provider = new WsProvider("ws://127.0.0.1:" + port);
// Utility script constructing a SCALE-encoded setStorage call from a key-value json array of
// genesis values by connecting to a running instance of the chain. (It is not required to be
// functional or synced.)
// connect to a substrate chain and return the api object
async function connect(endpoint, types = {}) {
const provider = new WsProvider(endpoint);
const api = await ApiPromise.create({
provider,
types,
@@ -14,28 +19,37 @@ async function connect(port, types) {
}
if (!process.argv[2] || !process.argv[3]) {
console.log("usage: node generate_keys <input json> <scale output file>");
exit();
console.log("usage: node generate_keys <input json> <scale output file> [rpc enpoint]");
exit();
}
const input = process.argv[2];
const output = process.argv[3];
// default to localhost and the default Substrate port
const rpcEnpoint = process.argv[4] || "ws://localhost:9944";
console.log("Processing", input, output);
fs.readFile(input, "utf8", (err, data) => {
if (err) {
console.log(`Error reading file from disk: ${err}`);
exit(1);
}
if (err) {
console.log(`Error reading file from disk: ${err}`);
exit(1);
}
const genesis = JSON.parse(data);
const genesis = JSON.parse(data);
connect(9944, {}).then(api => {
const setStorage = api.tx.system.setStorage(genesis);
const raw = setStorage.method.toU8a();
const hex = util.u8aToHex(raw);
fs.writeFileSync(output, hex);
exit(0)
}).catch(e => {
console.error(e);
exit(1)
});
console.log("loaded genesis, length = ", genesis.length);
console.log(`Connecting to RPC endpoint: ${rpcEnpoint}`);
connect(rpcEnpoint)
.then((api) => {
console.log('Connected');
const setStorage = api.tx.system.setStorage(genesis);
const raw = setStorage.method.toU8a();
const hex = util.u8aToHex(raw);
fs.writeFileSync(output, hex);
exit(0);
})
.catch((e) => {
console.error(e);
exit(1);
});
});