diff --git a/charts/node/examples/local-rococo/Chart.yaml b/charts/node/examples/local-rococo/Chart.yaml new file mode 100644 index 0000000..cf3dbed --- /dev/null +++ b/charts/node/examples/local-rococo/Chart.yaml @@ -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/" diff --git a/charts/node/examples/local-rococo/bootnode.yaml b/charts/node/examples/local-rococo/bootnode.yaml index 2333262..43721c1 100644 --- a/charts/node/examples/local-rococo/bootnode.yaml +++ b/charts/node/examples/local-rococo/bootnode.yaml @@ -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 diff --git a/charts/node/examples/local-rococo/parachain.yaml b/charts/node/examples/local-rococo/parachain.yaml index d008b1b..00ac324 100644 --- a/charts/node/examples/local-rococo/parachain.yaml +++ b/charts/node/examples/local-rococo/parachain.yaml @@ -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 \ No newline at end of file diff --git a/charts/node/examples/local-rococo/templates/configMap.yaml b/charts/node/examples/local-rococo/templates/configMap.yaml new file mode 100644 index 0000000..c496f78 --- /dev/null +++ b/charts/node/examples/local-rococo/templates/configMap.yaml @@ -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); + }); diff --git a/charts/node/examples/local-rococo/validators-alice-bob.yaml b/charts/node/examples/local-rococo/validators-alice-bob.yaml index b17ecdd..3e498cb 100644 --- a/charts/node/examples/local-rococo/validators-alice-bob.yaml +++ b/charts/node/examples/local-rococo/validators-alice-bob.yaml @@ -1,57 +1,46 @@ -image: - repository: parity/polkadot - tag: latest - pullPolicy: Always - node: - chain: rococo-local - customChainspecUrl: http://bootnode:8080/chainspec.json - forceDownloadChainspec: true - role: authority - 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: gran - scheme: ed25519 - # ${HOSTNAME##*-} will be evaluated as the pod index, pod-0: //Alice, pod-1: //Bob - extraDerivation: '$([ "${HOSTNAME##*-}" = "0" ] && echo "//Alice" || echo "//Bob")' - - seed: "bottom drive obey lake curtain smoke basket hold race lonely fit walk" - type: babe - scheme: sr25519 - extraDerivation: '$([ "${HOSTNAME##*-}" = "0" ] && echo "//Alice" || echo "//Bob")' - - seed: "bottom drive obey lake curtain smoke basket hold race lonely fit walk" - type: imon - scheme: sr25519 - extraDerivation: '$([ "${HOSTNAME##*-}" = "0" ] && echo "//Alice" || echo "//Bob")' - - seed: "bottom drive obey lake curtain smoke basket hold race lonely fit walk" - type: para - scheme: sr25519 - extraDerivation: '$([ "${HOSTNAME##*-}" = "0" ] && echo "//Alice" || echo "//Bob")' - - seed: "bottom drive obey lake curtain smoke basket hold race lonely fit walk" - type: asgn - scheme: sr25519 - extraDerivation: '$([ "${HOSTNAME##*-}" = "0" ] && echo "//Alice" || echo "//Bob")' - - seed: "bottom drive obey lake curtain smoke basket hold race lonely fit walk" - type: audi - scheme: sr25519 - extraDerivation: '$([ "${HOSTNAME##*-}" = "0" ] && echo "//Alice" || echo "//Bob")' - - seed: "bottom drive obey lake curtain smoke basket hold race lonely fit walk" - type: beef - scheme: ecdsa - extraDerivation: '$([ "${HOSTNAME##*-}" = "0" ] && echo "//Alice" || echo "//Bob")' - customNodeKey: - # To generate new key run: docker run --rm -t parity/polkadot:latest key generate-node-key - # 12D3KooWJ8ZqNMsxW9JHf8ZfXLW9a5LmJwaro83fB3tBzeq137XJ - - 2f355a92b3f2823975e8d59a022bd4927aca4b016359b7fc358cbea08b5293fc - # 12D3KooWCNqZFCPPtUGHhsUKzKWi1zTPwFFiobfCKdVYD4urrZEv - - 8b70f3e85bd5d80ebef8cffa8564f52e7d418b07b3cfb222712f30414dc67728 - flags: - - "--allow-private-ipv4" - - "--discover-local" + node: + chain: rococo-local + customChainspecUrl: http://bootnode:8080/chainspec.json + forceDownloadChainspec: true + role: authority + 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: gran + scheme: ed25519 + # ${HOSTNAME##*-} will be evaluated as the pod index, pod-0: //Alice, pod-1: //Bob + extraDerivation: '$([ "${HOSTNAME##*-}" = "0" ] && echo "//Alice" || echo "//Bob")' + - seed: "bottom drive obey lake curtain smoke basket hold race lonely fit walk" + type: babe + scheme: sr25519 + extraDerivation: '$([ "${HOSTNAME##*-}" = "0" ] && echo "//Alice" || echo "//Bob")' + - seed: "bottom drive obey lake curtain smoke basket hold race lonely fit walk" + type: imon + scheme: sr25519 + extraDerivation: '$([ "${HOSTNAME##*-}" = "0" ] && echo "//Alice" || echo "//Bob")' + - seed: "bottom drive obey lake curtain smoke basket hold race lonely fit walk" + type: para + scheme: sr25519 + extraDerivation: '$([ "${HOSTNAME##*-}" = "0" ] && echo "//Alice" || echo "//Bob")' + - seed: "bottom drive obey lake curtain smoke basket hold race lonely fit walk" + type: asgn + scheme: sr25519 + extraDerivation: '$([ "${HOSTNAME##*-}" = "0" ] && echo "//Alice" || echo "//Bob")' + - seed: "bottom drive obey lake curtain smoke basket hold race lonely fit walk" + type: audi + scheme: sr25519 + extraDerivation: '$([ "${HOSTNAME##*-}" = "0" ] && echo "//Alice" || echo "//Bob")' + - seed: "bottom drive obey lake curtain smoke basket hold race lonely fit walk" + type: beef + scheme: ecdsa + extraDerivation: '$([ "${HOSTNAME##*-}" = "0" ] && echo "//Alice" || echo "//Bob")' + customNodeKey: + # To generate new key run: docker run --rm -t parity/polkadot:latest key generate-node-key + - "0000000000000000000000000000000000000000000000000000000000000002" + - "0000000000000000000000000000000000000000000000000000000000000003" + flags: + - "--allow-private-ipv4" + - "--discover-local"