Bootstraper une ĞDev (runtime-400)

Je rends publique la conversation ci-dessous parce qu’elle contient des informations utiles à tous.


Par “bootstrap le réseau” tu entends bien :

  • démarrer un noeud
  • publier une image avec ce bootnode ?

Pourquoi est-ce qu’on ne fait pas une image sans bootnode ? On peut bien le communiquer séparément.

Non c’est beaucoup plus de boulot que juste “démarrer un nœud”, pour bootstraper un réseau le 1er nœud doit être configuré et lancé de manière très spéciale.

Sait tu as partir de quel jour tu pourras te dégager un créneau de 2h? (Il faut au moins ça pour bootstrapper un live network).

J’ai commencé à compléter la documentation docs/dev/launch-a-live-network.md avec les notes prises lors de notre session il y a 9 jours. (ticket #91, MR !114)

Je suis désolé de devoir te redemander certaines choses que tu m’as déjà expliqué, je n’ai pas réussi à prendre des notes assez précises. Voici donc mes questions :

répartition des tâches automatisées

les tâches sont réparties suivant plusieurs systèmes

  • des CI GitLab
    • sur master
      • build_release_manual
      • deploy_docker_release_sha
    • sur release
      • build_release
      • deploy_docker_release_tag
  • des scripts xtask
    • release-runtime
    • inject-runtime-code
  • des scripts bash
    • gen-live-network-raw-spec.sh
    • create-live-network.sh
  • des appels docker
    • key generate
    • key generate-session-keys

est-ce que certaines de ces tâches sont appelées à changer ? Par exemple migrer des scripts bash vers des xtask, ou générer les session keys du premier nœud dans une xtask.

à propos de docker

Dans la pipeline de publication des images docker, je vois

WARNING! Using --password via the CLI is insecure.

Où peut-on voir l’ensemble des images docker ? Que contiennent-elles (client sans runtime, client avec runtime, runtime…) ? Que fournit-on aux smith comme docker-compose.yml ? Quand donne-t-on l’information du bootnode (adresse ip / dns par exemple) ?

rotation des session keys

Quelle est la méthode recommandée pour remplacer les session keys de l’autorité genesis ? Via l’API RPC contactée par polkadotjs sur tunnel ssh ?

que fournit-on aux smith ?

Quand on est prêt à ce que les autres smith rejoignent le réseau, que leur fournit-on ?

  • le nom d’une image docker ?
  • un bootnode ?

Par quel biais obtiennent-ils les session keys de notre autorité ?

processus général

Je ne suis pas sûr d’avoir bien compris l’ordre des étapes. Est-ce le suivant ?

  1. compilation du runtime avec srtool (+ publication, + publication image docker)
  2. génération locale des session keys de l’autorité du genesis, ajout dans les chainspec, génération des raw chainspec (mais avec le binaire du runtime compilé sans srtool)
  3. injection du runtime compilé avec srtool dans les raw chainspec
  4. lancement du nœud validateur avec ces raw chainspec
  5. rotation des session keys
  6. appel aux smith pour qu’ils démarrent leurs noeuds validateurs

Pas seulement sur master, sur toutes les branches à tous les commits pushés.

Je ne sais pas, j’ai fait ce qu’il me semblait le plus simple, si vous avez des suggestions pour simplifier tout ça, vous pouvez porposer, mais ça ne me semble pas prioritaire. Bootstrapper un réseau reste une tache de mainteneur uniquement, donc il ne fait mettre trop d’énergie à essayer de la rendre plus “accessible”.

Sur dockerhub sur le compte duniterteam. Mais je ne sais pas ce que tu veux voir exactement.

Les dockerfile sont tous dans le dossier docker/ du dépôt, il n’y en a que 2.

Un client n’est jamais sans runtime, c’est impossible. Tout client contient à minima 1 runtime “natif” pour chaque type de runtime (gdev/gtest/g1 selon rust features activées).
Un client peut en plus contenir des embedded raw specs, qui contiennent alors le bytecode d’un ou plusieurs runtime(s).

Toutes les images docker contiennent le client, donc un seul fichier binaire, qui embarque toujours au moins un runtime “natif”, et éventuellement d’autres runtimes selon le code compilé.

Via le call RPC author_rotateKeys sru l’api RPC privée du nœud, ça peut être fait avec curl, avec un script, via polkadotjs, qu’importe.

Le nom et le tag de l’image docker qu’ils doivent utiliser. cette image docker doit contenir un binaire qui embarque les raw chains spec définitives du nouveau réseau.

Dans le genesis state (qui est inclus dans les raw chain spec).

Avant l’appel aux smiths, il maque une étape: publier un nouveau client (et son image docker) qui embarque les raw chain spec définitives de ce nouveau réseau.

1 Like

D’accord, merci beaucoup, ça m’éclaire bien. Il me manque juste une information : comment les smith obtiennent ils l’adresse ip / le nom de domaine du bootnode ? Ils doivent bien le renseigner dans leur docker-compose ou quelque part ?

Quel est l’intérêt d’avoir la CI deploy_docker_release_sha sachant que de toute façon on va publier une autre image docker avec le runtime ?

Donc il faut faire une nouvelle fois cargo xtask release-runtime 400 ? Et écraser la version précédente de ce runtime ? Et écraser l’image docker ?

On peut s’appeler si tu es disponible et si tu préfères faire à l’oral que par écrit. [edit] je dois sortir un moment, je préviens en rentrant si tu veux

Non, on renseigne les bootnodes dans les raw spec, on peut d’ailleurs les modifier de temps en temps, il suffit alors de livrer une nouvelle version du client.

Non, je parle de publier un client, pas un runtime. La publication d’un nouveau client n’est pas automatisé, il faut tout faire à la main.

1 Like

D’accord, je n’avais compris cette étape d’ajout d’un bootnode dans les raw spec suivi de la livraison d’un nouveau client ayant ces raw spec en embedded, je vais faire apparaître ça dans la documentation.

Y a-t-il une raison de publier le binaire du runtime et pas simplement le tag du code et le hash du binaire ? En effet on attend de toutes les personnes qui votent le runtime upgrade qu’elles établissent la correspondance entre le code et le hash en compilant de leur côté, le runtime étant publié via la pallet preimage après le vote.

Par ailleurs, je vois que dans le script create-live-network.sh, il y a la génération automatisée des session keys. Est-ce qu’on peut donc enlever leur génération manuelle de la documentation ?

C’est plus pratique d’avoir déjà le wasm à dispo pour différentes taches techniques, notamment du test.

1 Like

Ce script n’injecte pas les session keys dans la genesis conf, il faut le faire à la main. Il régénère les sessions keys à partir du mnemonic donné en paramètre pour pouvoir les inclures dans le keystore du nœud validateur.

1 Like

Ce n’est pas automatisé avec la CI GitLab ? (qu’il faut lancer manuellement, mais il n’y a rien de plus à faire, si ?)

J’aimerais mettre au clair le processus de bootstrap. Dans ma vision des choses, voilà le jeu de poupées russes :

screenshot

Donc il faut

  1. compiler le runtime avec srtool
  2. choisir le genesis state
  3. écrire les raw chainspec sans bootnode, y injecter le runtime de l’étape (1.), et y écrire les session keys du premier noeud (générées à l’avance)
  4. compiler un client en mode release avec ces chainspecs
  5. publier une image docker basée sur ce client
  6. démarrer un premier noeud en utilisant l’image docker
  7. ajouter ce noeud aux bootnodes des chainspec
  8. publier une nouvelle image docker identique à l’exception du bootnode
  9. démarrer d’autre noeuds avec cette nouvelle image docker

Est-ce valide ? (les étapes 7, 8, 9 sont optionnelles, on pourrait tout à fait publier un docker compose qui contient les bootnodes en command line arguments)

Ça me permettra de compléter

en contextualisant un peu. Parce qu’avec tous les détails techniques :

  • binaire duniter degub/release
  • CI GitLab
  • scripts bash
  • xtasks
    • compilation avec le docker srtool
    • publication du runtime
  • appels docker

je m’y perds un peu. J’aimerais bien réécrire cette doc en faisant apparaître la théorie dans la structure, et la pratique dans le contenu. Pour l’instant tout est un peu mélangé je trouve.

Par ailleurs, le fait d’utiliser des commandes docker dans ce processus nécessite d’avoir publié des images au préalable, ce qui complique la démarche. Pour moi docker ne devrait être utilisé que pour faciliter le déploiement sur un serveur, pas pour exécuter des commandes Duniter en local (sauf srtool).

Pas tout à fait d’accord avec ça. Plus c’est compréhensible, plus facilement on peut faire rentrer des devs dans ce processus qui permet de comprendre comment fonctionne substrate. De plus il y a une différence entre bootstraper un réseau de dev et un réseau de prod. Dans un réseau de dev on peut :

  • ne pas rotate les session keys, ce qui permet de renseigner le bootnode dès le début et d’éviter d’avoir à publier une deuxième image
  • (ou) ne pas renseigner de bootnode et attendre des autres participants du réseau de dev qu’ils l’ajoutent dans leur docker-compose

Des réseaux de dev on peut vouloir en monter pour différentes raisons, c’est mieux si c’est simple et rapide. Effectivement dans un réseau de prod il faut prendre des précautions de sécurité supplémentaires qu’il faut documenter, et pas forcément chercher à rendre accessible.

3 Likes

Pour avoir l’image docker rien de plus en effet, mais c’est mieux de créer également une page de release sur le gitlab avec un petit changelog.
Ça permet également d’y inclure d’autres livrables, comme un binaire armv7 par exemple.

Cette donnée est a renseignée dans la genesis conf, donc avant de générer les raw chain spec

Non pas besoin. Les raw chain spec sont dans un fichier json qui est injecté en ligne de commande --chain=path/to/raw/spec.json.
Mais il faut quand meme build un client en mode release sur le tag du runtime pour s’assurer d’avoir un client compatible avec le genesis runtime.

Lec commandes docker sont dans un script qui à vocation à être exécuté sur le serveur de bootstrap, pas uniquement sur une machine de dev en local. Passer par docker permet de ne pas avoir à installer d’environnement de dev sur le serveur, ça me semble au contraire beaucoup plus propre.

Déployer un réseau n’est pas une tache de dev, ça doit pouvoir se faire sans avoir rust.

1 Like

Ce point n’est pas très clair, je ne vois pas d’informations sur comment réaliser l’injection. :confused:

edit : je vais l’injecter moi-même en rajoutant une variable d’environnement WASM_FILE, mais je suis étonné que le processus ne soit pas déjà prévu par Substrate.

Il y a un script xtask de elois à ce sujet :

# toutes les xtasks 
> cargo xtask help
Usage: xtask <COMMAND>

Commands:
  build                Build duniter binary
  gen-calls-doc        Generate calls documentation
  inject-runtime-code  Inject runtime code in raw specs
  release-runtime      Release a new runtime
  test                 Execute unit tests and integration tests End2tests are skipped
  help                 Print this message or the help of the given subcommand(s)

Options:
  -h, --help  Print help

# les options de inject-runtime-code
> cargo xtask inject-runtime-code --help 
Inject runtime code in raw specs

Usage: xtask inject-runtime-code --runtime <RUNTIME> --raw-spec <RAW_SPEC>

Options:
  -r, --runtime <RUNTIME>    Runtime filepath
  -s, --raw-spec <RAW_SPEC>  Raw spec filepath
  -h, --help                 Print help

Ça fait rien de plus que remplacer le code dans les chainspecs.

J’imagine que côté substrate ils font ça côté github actions :

  • srtool-actions provides Github actions to integrate builds produced using the srtool image with your GitHub CI/CD pipelines.

(citation extraite de la page https://docs.substrate.io/reference/command-line-tools/srtool/)

Ah mince je ne l’ai pas vue :frowning:

Ceci dit, je préfère autant l’implémentation que j’ai faite car ça permet de lancer le nœud avec le bon Runtime sans même construire un fichier de specs (plain ou raw).

Sauf si ça dérange vraiment, je vais laisser dans cet état-là avec l’ajout de WASM_FILE.

Côté Substrate, OK mais je ne vais pas creuser pour vérifier. Ce n’est pas très important, c’est juste que leur documentation est généralement bien faite et détaillée, or là sur un sujet aussi essentiel pour bootstraper convenablement une monnaie il manque la doc, qui aurait dû être mise à jour quand srtool a été créé.

Bref :slight_smile:

1 Like

Tu as raison, ça me manquait aussi de pouvoir lancer un nœud avec un runtime construit ailleurs sans passer par un fichier de specs. WASM_FILE me paraît être un bon ajout.

1 Like