Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
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: 9 additions & 0 deletions charts/node/examples/local-rococo/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
apiVersion: v2
name: simple-relay-parachain
description: A Helm chart for Kubernetes
type: application
version: 0.1.0
dependencies:
- name: node
version: "5.15.0"
repository: "https://paritytech.github.io/helm-charts/"
122 changes: 53 additions & 69 deletions charts/node/examples/local-rococo/bootnode.yaml
Original file line number Diff line number Diff line change
@@ -1,73 +1,57 @@
fullnameOverride: bootnode
node:
fullnameOverride: bootnode

image:
repository: parity/polkadot
tag: latest
pullPolicy: Always
node:
chain: rococo-local
customChainspec: true # see extraInitContainers, chainspec-generator
role: full
replicas: 1
chainData:
pruning: archive
storageClass: ""
chainKeystore:
mountInMemory:
enabled: true
perNodeServices:
relayP2pService:
enabled: true
# to generate new key run: docker run parity/polkadot key generate-node-key
# 12D3KooWRpzRTivvJ5ySvgbFnPeEE6rDhitQKL1fFJvvBGhnenSk
customNodeKey: "0000000000000000000000000000000000000000000000000000000000000001"

node:
chain: rococo-local
customChainspec: true # see extraInitContainers, chainspec-generator
role: full
replicas: 1
chainData:
pruning: archive
storageClass: ""
chainKeystore:
mountInMemory:
enabled: true
perNodeServices:
relayP2pService:
enabled: true
# to generate new key run: docker run parity/polkadot key generate-node-key
# 12D3KooWRpzRTivvJ5ySvgbFnPeEE6rDhitQKL1fFJvvBGhnenSk
customNodeKey: 80c30ac6ba927c6e5c0c9681aa9674f1d181d180853bcd3485cee9d18e931238
flags:
- "--allow-private-ipv4"
- "--discover-local"
flags:
- "--allow-private-ipv4"
- "--discover-local"

# RPC endpoint
ingress:
enabled: false
annotations:
kubernetes.io/ingress.class: TODO
external-dns.alpha.kubernetes.io/target: TODO
cert-manager.io/cluster-issuer: TODO
host: local-rococo.example.com
tls:
- secretName: local-rococo.example.com
hosts:
- local-rococo.example.com
# Generate chainspec, and expose it as url
extraInitContainers:
- name: chainspec-generator
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
securityContext:
runAsUser: 0
command: [ "/bin/bash" ]
args:
- -c
- |
apt update && apt install -y jq
{{ .Values.node.command }} build-spec --chain {{ .Values.node.chain }} > base.json
echo '{"bootNodes":["/dns/bootnode-0/tcp/30333/p2p/12D3KooWEyoppNCUx8Yx66oV9fJnriXwCcXwDDUA2kj6vnc6iDEp"]}' > override1.json
jq -s '.[0] * .[1]' base.json override1.json | sed 's/1e+18/1000000000000000000/' > plain.json
cut -c -256 plain.json
{{ .Values.node.command }} build-spec --chain plain.json --raw > chainspec.json
cp chainspec.json {{ .Values.node.customChainspecPath }}
volumeMounts:
- mountPath: /chain-data
name: chain-data
extraContainers:
- name: chainspec
image: nginxinc/nginx-unprivileged:stable
ports:
- containerPort: 8080
name: web
volumeMounts:
- name: chain-data
subPath: chainspec.json
mountPath: /usr/share/nginx/html/chainspec.json
readOnly: true

# Generate chainspec, and expose it as url
extraInitContainers:
- name: chainspec-generator
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
securityContext:
runAsUser: 0
command: [ "/bin/bash" ]
args:
- -c
- |
apt update || true
apt install -y jq
{{ .Values.node.command }} build-spec --chain {{ .Values.node.chain }} > base.json
echo '{"bootNodes":["/dns/bootnode-0/tcp/30333/p2p/12D3KooWRpzRTivvJ5ySvgbFnPeEE6rDhitQKL1fFJvvBGhnenSk"]}' > override1.json
jq -s '.[0] * .[1]' base.json override1.json | sed 's/1e+18/1000000000000000000/' > plain.json
cut -c -256 plain.json
{{ .Values.node.command }} build-spec --chain plain.json --raw > chainspec.json
cp chainspec.json {{ .Values.node.customChainspecPath }}
volumeMounts:
- mountPath: /chain-data
name: chain-data
extraContainers:
- name: chainspec
image: nginxinc/nginx-unprivileged:stable
ports:
- containerPort: 8080
name: web
volumeMounts:
- name: chain-data
subPath: chainspec.json
mountPath: /usr/share/nginx/html/chainspec.json
readOnly: true
125 changes: 51 additions & 74 deletions charts/node/examples/local-rococo/parachain.yaml
Original file line number Diff line number Diff line change
@@ -1,78 +1,55 @@
image:
repository: parity/polkadot-parachain
tag: latest
pullPolicy: Always

node:
chain: asset-hub-rococo-local
command: polkadot-parachain
role: collator
replicas: 2
chainData:
pruning: 1000
storageClass: ""
chainKeystore:
storageClass: ""
keys:
# This is Alice seed. To generate new seed run: docker run --rm parity/polkadot:latest key generate
- seed: "bottom drive obey lake curtain smoke basket hold race lonely fit walk"
type: aura
scheme: sr25519
# ${HOSTNAME##*-} will be evaluated as the pod index, pod-0: //Alice, pod-1: //Bob
extraDerivation: '$([ "${HOSTNAME##*-}" = "0" ] && echo "//Alice" || echo "//Bob")'
customNodeKey:
# To generate new key run: docker run --rm -t parity/polkadot:latest key generate-node-key
# 12D3KooWL5Av1ZZSKkaittmxXBmZpzP7zgiB1AAnWHEw7MxzqnFp
- bdf71a910354e231095366230621eaefb5f99465045f1501478fd3d9b5deef98
# 12D3KooWAxFonTS177T81CTDeH6mfvJQWYEJeVQ1gPrnULjNY8Cn
- 2a775a9db9fb0ff40afacb4aa7ccbf2a5d04c6d980bb1437c196c8e38a6cd948
flags:
- "--bootnodes /dns/parachain-node-0/tcp/30334/p2p/12D3KooWL5Av1ZZSKkaittmxXBmZpzP7zgiB1AAnWHEw7MxzqnFp"
isParachain: true
collatorRelayChain:
chain: rococo-local
customChainspecUrl: http://bootnode:8080/chainspec.json
forceDownloadChainspec: true
chainData:
storageClass: ""
image:
repository: parity/polkadot-parachain

node:
chain: asset-hub-rococo-local
command: polkadot-parachain
role: collator
replicas: 2
keys:
# This is Alice seed. To generate new seed run: docker run --rm parity/polkadot:latest key generate
- seed: "bottom drive obey lake curtain smoke basket hold race lonely fit walk"
type: aura
scheme: sr25519
# ${HOSTNAME##*-} will be evaluated as the pod index, pod-0: //Alice, pod-1: //Bob
extraDerivation: '$([ "${HOSTNAME##*-}" = "0" ] && echo "//Alice" || echo "//Bob")'
customNodeKey:
- "0000000000000000000000000000000000000000000000000000000000000004"
- "0000000000000000000000000000000000000000000000000000000000000005"
flags:
- "--allow-private-ipv4"
- "--discover-local"
# This corresponds to the generated node key
- "--bootnodes /dns/parachain-node-0/tcp/30334/p2p/12D3KooWSsChzF81YDUKpe9Uk5AHV5oqAaXAcWNSPYgoLauUk4st"
isParachain: true
collatorRelayChain:
chain: rococo-local
customChainspecUrl: http://bootnode:8080/chainspec.json
forceDownloadChainspec: true
flags:
- "--allow-private-ipv4"
- "--discover-local"

# RPC endpoint
ingress:
enabled: false
annotations:
kubernetes.io/ingress.class: TODO
external-dns.alpha.kubernetes.io/target: TODO
cert-manager.io/cluster-issuer: TODO
host: parachain.example.com
tls:
- secretName: parachain.example.com
hosts:
- parachain.example.com
extraInitContainers:
- name: dump-state-and-wasm
image: "parity/polkadot-parachain:latest"
securityContext:
runAsUser: 0
command: [ "/bin/bash" ]
args:
- -c
- |
if [ "${HOSTNAME##*-}" = "0" ]; then
echo "Parachain Id:"
{{ .Values.node.command }} build-spec --chain {{ .Values.node.chain }} | grep -E 'para_id|parachainId'
echo "Genesis head:"
{{ .Values.node.command }} export-genesis-state --chain {{ .Values.node.chain }}
echo ""
echo "Genesis wasm (validationCode) stored in /chain-data/genesis-wasm"
{{ .Values.node.command }} export-genesis-wasm --chain {{ .Values.node.chain }} > /chain-data/genesis-wasm
else
echo "Genesis head and wasm are in pod ${HOSTNAME%-*}-0"
fi
volumeMounts:
- mountPath: /chain-data
name: chain-data

extraInitContainers:
- name: dump-state-and-wasm
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: "{{ .Values.image.pullPolicy }}"
securityContext:
runAsUser: 0
command: [ "/bin/bash" ]
args:
- -c
- |
if [ "${HOSTNAME##*-}" = "0" ]; then
echo "Parachain Id:"
{{ .Values.node.command }} build-spec --chain {{ .Values.node.chain }} | grep -E 'para_id|parachainId'
echo "Genesis head:"
{{ .Values.node.command }} export-genesis-state --chain {{ .Values.node.chain }}
echo ""
echo "Genesis wasm (validationCode) stored in /chain-data/genesis-wasm"
{{ .Values.node.command }} export-genesis-wasm --chain {{ .Values.node.chain }} > /chain-data/genesis-wasm
else
echo "Genesis head and wasm are in pod ${HOSTNAME%-*}-0"
fi
volumeMounts:
- mountPath: /chain-data
name: chain-data
78 changes: 78 additions & 0 deletions charts/node/examples/local-rococo/templates/configMap.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
---
apiVersion: v1
kind: ConfigMap
metadata:
name: xcm-init-script
data:
submit.js: |
import { ApiPromise, WsProvider } from '@polkadot/api';

function toHexString(byteArray) {
return Array.from(byteArray, function(byte) {
return ('0' + (byte & 0xFF).toString(16)).slice(-2);
}).join('');
}

async function getWasmCode(api) {
const wasmCode = await api.query.substrate.code();

if (wasmCode.isEmpty) {
throw new Error(`No validation code found for hash ${codeHash.toHex()}`);
}

return wasmCode;
}

async function getGenesisHead(api) {
// Get the genesis block hash
const genesisHash = await api.rpc.chain.getBlockHash(0);

// Get the genesis block
const genesisBlock = await api.rpc.chain.getBlock(genesisHash);
console.log("Genesis block: ", JSON.stringify(genesisBlock));

// Extract the required fields
const parentHash = genesisBlock.block.header.parentHash.toString();
const stateRoot = genesisBlock.block.header.stateRoot.toString();
const extrinsicsRoot = genesisBlock.block.header.extrinsicsRoot.toString();

console.log("State root: ", JSON.stringify(stateRoot));
// Construct the genesis head according to your requirements
const genesisHead = parentHash + '00' + stateRoot.replace('0x', '') + extrinsicsRoot.replace('0x', '') + '00';

return genesisHead;
}

async function main() {
const PARACHAIN_ENDPOINT = 'ws://localhost:9945';

const wsProvider = new WsProvider(PARACHAIN_ENDPOINT);
const api = await ApiPromise.create({ provider: wsProvider });

const paraKind = true;

try {
const wasm = await getWasmCode(api);
const hexedWasm = toHexString(wasm);

const genesisHead = await getGenesisHead(api);
console.log(genesisHead);

// slots.forceLease()
// https://polkadot.js.org/docs/kusama/extrinsics#forceleasepara-u32-leaser-accountid32-amount-u128-period_begin-u32-period_count-u32
// api.tx.slots.forceLease(para: u32, leaser: AccountId32, amount: u128, period_begin: u32, period_count: u32)

} catch (error) {
console.error('A call has failed: ', error.message);
throw error;
}
}

main().catch(console.error);



main().catch((error) => {
console.error('Fatal error:', error);
process.exit(1);
});
Loading