Proposition: Supprimer le comité technique

Je propose de supprimer le comité technique et de confier les mises à jour du runtime aux forgerons actifs. Une mise à jour serait autorisée dès que strictement plus de deux tiers d’entre eux l’approuvent, puis appliquée on-chain, sans fork.

C’est moi qui avais proposé la création d’un comité technique en mai 2022, puis annoncé sa mise en place dans la ĞDev en août 2022. J’avais aussi défendu son rôle au nom de l’expertise technique de ses membres.

À l’origine, je voulais éviter de concentrer les pouvoirs et distinguer deux responsabilités qui demandent des compétences différentes. Administrer un nœud et participer au consensus ne demande pas les mêmes connaissances que comprendre le code du runtime et évaluer les conséquences de ses modifications. C’est cette réflexion qui m’avait conduit à proposer un comité technique.

Je souhaite aujourd’hui revenir sur ce choix. La distinction des compétences reste valable, mais elle ne justifie plus, à mes yeux, de maintenir un comité doté d’un pouvoir privilégié. D’autant que cette séparation ne retire pas aux forgerons leur capacité à changer les règles par un hard fork lorsque les deux tiers d’entre eux s’accorde pour le faire.

La pratique m’a aussi amené à revoir l’argument de l’expertise. Être membre du comité technique ne signifie pas forcément mieux comprendre le code du runtime et ses évolutions qu’un forgeron. Lors du vote sur le runtime 1100 de la ĞTest, plusieurs membres ont expliqué avoir voté sans relire le code, en s’appuyant sur le travail et les avis d’autres personnes.

Moul indiquait ne pas avoir les compétences ni le temps nécessaires pour auditer le Rust. Il avait examiné le changelog, les MR et les échanges du forum, puis accordé sa confiance. Vit expliquait également avoir vérifié les hashes et voté sans revoir le code, en faisant confiance aux fondateurs de la Ğ1 qui avaient voté.

Je comprends cette démarche. On ne peut pas demander à chacun de maîtriser tout le code de Duniter. Mais vérifier qu’un runtime correspond au code publié et juger si ce code est correct sont deux vérifications différentes. Si le vote repose en partie sur la confiance accordée aux développeurs, les forgerons peuvent eux aussi prendre une décision sur cette base.

L’expertise collective que j’attendais du comité ne se traduit donc pas, en pratique, par la vérification indépendante du code que j’avais en tête. Les raisons pour lesquelles je défendais ce comité ne se vérifient pas comme je l’espérais. Il me paraît cohérent d’en tirer les conséquences et de proposer sa suppression.

Dans Duniter v1, nous faisions évoluer le protocole par des hard forks. Cette possibilité existe toujours dans Duniter v2.

Substrate (aujourd’hui renommé Polkadot SDK), permet à un opérateur de remplacer localement le runtime on-chain grâce au champ codeSubstitutes de la configuration de chaîne. La substitution prend effet à partir d’un bloc donné et reste applicable jusqu’à un changement de spec_version on-chain. Le fonctionnement est décrit dans le code du Polkadot SDK.

Si strictement plus de deux tiers des forgerons adoptent la même substitution au même bloc, ils peuvent poursuivre la chaîne avec les nouvelles règles et en finaliser les blocs. C’est le seuil requis par GRANDPA.

Les nœuds restés sur l’ancien runtime ne peuvent plus suivre dès que les nouvelles règles produisent un résultat différent. Le tiers des forgerons restant doivent alors se mettre à jour pour reprendre leur participation. Sans cela, ils sortent de l’ensemble des forgerons actifs au bout de quelques heures.

Cela touche aussi les nœuds RPC. Leurs opérateurs doivent adopter la substitution pour continuer à suivre la chaîne et à servir les applications. Un hard fork demande donc de coordonner bien plus que les seuls forgerons, avec un risque d’interruption de service pour les utilisateurs.

Le comité technique nous évite aujourd’hui cette coordination. Il autorise la publication du nouveau runtime on-chain, que les nœuds exécutent ensuite automatiquement. C’est le principe des mises à jour sans fork du Polkadot SDK. Je propose de conserver ce fonctionnement en faisant venir l’autorisation directement des forgerons.

Concrètement, une pallet permettrait à chaque forgeron actif d’enregistrer un marqueur contenant le hash du runtime qu’il approuve.

  1. Chaque forgeron actif peut enregistrer son soutien à un hash de runtime.
  2. Dès que strictement plus de deux tiers des forgerons actifs soutiennent le même hash, la mise à jour est autorisée automatiquement.
  3. N’importe qui peut alors publier le code correspondant on-chain. La pallet vérifie que son hash correspond exactement au hash approuvé avant d’appliquer la mise à jour.

Le forgeron dont le soutien fait franchir le seuil pourrait fournir le code dans la même transaction, pour déclencher immédiatement la mise à jour.

On pourrait ainsi distribuer le runtime proposé avec une nouvelle version de Duniter. En installant cette version, le forgeron signalerait son accord par la publication du marqueur. L’installation n’activerait aucune substitution locale, puisque la mise à jour attendrait l’accord de la supermajorité.

Une fois approuvé et publié on-chain, le nouveau runtime serait exécuté automatiquement par tous les nœuds compatibles. Cela inclut les forgerons qui n’ont pas soutenu la proposition et les nœuds RPC. Les opérateurs RPC n’auraient donc pas à synchroniser une mise à jour de leur logiciel avec la décision des forgerons.

C’est ce qui motive ma proposition. Les deux tiers des forgerons dispose déjà du pouvoir technique de changer les règles et de poursuivre la chaîne par un hard fork. Je propose de permettre l’exercice de cette capacité directement on-chain, pour conserver les mises à jour sans hard fork pour en éviter les perturbations.

Le travail des développeurs resterait tout aussi nécessaire pour proposer, expliquer, auditer et tester les mises à jour. Les forgerons s’appuieraient sur ce travail pour décider de les adopter, comme ils le font lorsqu’ils choisissent une version du logiciel à installer. Les personnes capables de relire le runtime pourraient continuer à partager leurs analyses. Ce travail n’a pas besoin d’être associé à un pouvoir privilégié détenu par un comité.

Qu’en pensez-vous ?

Si je comprends bien, ce qui était demandé aux membres du comité technique serait maintenant demandé à X forgerons actifs. Soit une opération manuelle avant de déclencher la mise à jour.

Le premier problème que je vois est que X va augmenter avec le temps alors que le nombre de membres du comité technique restera plutôt stable. Il sera donc bien plus difficile de contacter X forgerons pour leur demander de mettre à jour, que de demander cela aux quelques membres du comité. Les votes de celui-ci demandaient déjà du temps pour contacter les membres, avec 2/3 des forgerons à contacter ce sera pire. Amha.

Je pense surtout aux failles zéro day à mettre à jour rapidement…

Sinon j’aime bien l’idée, je trouve cela plus organique, moins centralisé.

Je n’ai sans doute pas été assez clair sur ce point. Dans le fonctionnement que je propose, les forgerons n’auraient pas à effectuer un vote manuel en plus de la mise à jour de leur nœud. La version de Duniter installée publierait automatiquement leur soutien au runtime qu’elle embarque.

Il resterait donc à choisir d’installer cette version, mais aucune manipulation supplémentaire ne serait nécessaire pour approuver le runtime.

C’est d’ailleurs déjà le cas pour les hard forks : il suffit que deux tiers des forgerons installent une même version de Duniter qui contient le runtime substitué pour déclencher le hard fork.

Oui, réunir l’accord d’un plus grand nombre de personnes peut prendre davantage de temps. C’est aussi une conséquence de la décentralisation que je trouve souhaitable pour les changements de règles. Plus le réseau compte de forgerons indépendants, plus il faut obtenir une adhésion large avant de modifier son fonctionnement. Cela limite la possibilité qu’un petit groupe impose un changement.

L’automatisation du soutien ne supprime pas ce besoin de coordination. Elle évite simplement d’ajouter une procédure de vote à la mise à jour habituelle du logiciel.

Sur ce point, il faut distinguer les vulnérabilités du runtime de celles du binaire Duniter.

Lors de l’audit de sécurité que j’ai réalisé avec les modèles d’OpenAI, les vulnérabilités que j’ai trouvées concernaient le binaire, pas le runtime. Leur correction a nécessité la mise à jour Duniter v2.3.0. Une décision du comité technique ne pouvait pas déployer ces correctifs sur les machines des opérateurs : chacun devait mettre à jour son nœud.

Même avec le comité technique, nous devons donc déjà être capables de joindre rapidement les forgerons, et plus largement les opérateurs de nœuds, en cas de faille dans le binaire. Le groupe Telegram des forgerons v2 sert notamment à cela. On peut discuter d’autres canaux pour que les alertes importantes atteignent tout le monde.

Cela ne signifie évidemment pas qu’il ne peut pas y avoir de faille dans le runtime. Dans ce cas, un comité restreint pourrait effectivement autoriser un correctif plus vite qu’une supermajorité de forgerons. C’est un avantage du système actuel, et un compromis à discuter.

Ce besoin de réactivité existe déjà aujourd’hui, quel que soit le devenir du comité technique.