GTest - Runtime upgrade 1100

Suite aux changements de dernières minutes initiés par @elois ces derniers jours (merci à lui), au vue de préparer le lancement de la g1 sur duniter v2s la semaine prochaine, une mise à jour de la gtest est nécessaire afin de valider ces modifications.

Pour rappel, voici les points notables de ces changements :

  • MR !362:
    1. ReportLongevity : passe de 168 * EPOCH_DURATION (~7 jours) à 28 * 24 * EPOCH_DURATION (28 jours) — les rapports d’équivocation restent valides beaucoup plus longtemps
    2. ChangeOwnerKeyPeriod : passe de 1 MONTHS à 6 MONTHS — délai entre deux changements de clé owner multiplié par 6
    3. IdtyCreationPeriod : passe de 1 DAYS à 5 DAYS — délai entre deux créations d’identité multiplié par 5
  • create_identity requiert désormais un compte existant (#321) : le compte destinataire doit avoir été préalablement crédité avant de pouvoir y créer une identité. Sinon, l’erreur AccountNotExist est retournée.
  • Correction du remboursement de fee après change_owner_key (#356) : lors d’un batch_all(claim_uds, transfer_all, change_owner_key), le refund de fee est maintenant correctement
    envoyé vers la nouvelle clé owner, et non plus vers l’ancienne (qui est vide après le transfert).
  • API GRANDPA equivocation désormais fonctionnelle (#351) : submit_report_equivocation_unsigned_extrinsic et generate_key_ownership_proof étaient des stubs retournant None. Ils sont maintenant implémentés, ce qui permet de signaler et sanctionner les équivocations GRANDPA on-chain.
  • Correction de la parité comportementale GTest/G1 (#349) : MembershipRenewalPeriod corrigé de 56 * DAYS à 2 * MONTHS sur GTest, et ajout du ProxyType::TechnicalCommitteePropose
    sur G1 (déjà présent sur GTest).
  • Refactor du handler change_owner_key pour les forgerons (#327) : le code vérifie maintenant directement l’existence du membre via Members::contains_key plutôt que de matcher sur une chaîne d’erreur fragile. Pas de changement comportemental.
  • Amélioration des benchmarks et recalcul des poids (#346) : meilleure couverture worst-case pour authority_members, identity, quota et smith_members. Tous les poids ont été
    regénérés.
  • Migration vers Rust stable 1.88.0 (#355) : le projet passe de nightly à stable, avec le nouveau target WASM wasm32v1-none.
  • Graphe de certification smith explicite pour la genèse G1 : remplacement du mode clique automatique par un graphe de certifications manuelles (chaque forgeron reçoit exactement 3 certifications).

Hormis cet update, je vais également réaliser de mon côté de lancement du runtime g1 à blanc cette semaine, pour valider que tout va bien , notamment au niveau des déclaration de clic smith.


Vérification du runtime par les membres du TC

Aucune migration de storage n’est nécessaire pour cet upgrade (aucun type de storage n’a changé). Le spec_version passe de 1000 à 1100.

La branche correspondante est runtime/gtest-1100.

La procédure de vérification du hash blake2_256 est documentée ici :
verify-runtime-code.md

En résumé :

  1. Compiler le runtime depuis la branche :
git checkout runtime/gtest-1100
cargo xtask release runtime build gtest
  1. Récupérer le hash blake2_256 de votre build :
    cat release/srtool_output_gtest.json | grep blake2_256 | jq -r '.runtimes.compressed.blake2_256'

  2. Comparer avec le hash de la preimage on-chain (voir la doc ci-dessus pour la méthode complète).

Comment voter

Une fois la preimage soumise, rendez-vous sur Duniter Portal connecté à la GTest :

  1. Allez dans Governance > Tech. committee > Proposals
  2. Votez pour la proposition 8, code byte 0xa722bfc4eecc71e854d668c5700f99fd173c30d6bd29b39d685d162b05597ed3
    ping @technical-committee
7 Likes

@poka a oublié un changement qui impacte le comportement du runtime gtest. Je ne dirai pas de quelle MR il s’agit, afin d’inciter les membres du comité technique à vérifier eux-mêmes les commits entre les deux runtimes et à identifier le changement qui à été oublié

5 Likes

Ah oui pardon, en effet, le plus impactant en plus ^^

3 Likes

Bon je le rajoute quand même vue que le temps presse un peu pour tester ce runtime avant Dimanche:

  • MR !362:

    1. ReportLongevity : passe de 168 * EPOCH_DURATION (~7 jours) à 28 * 24 * EPOCH_DURATION (28 jours) — les rapports d’équivocation restent valides beaucoup plus longtemps
    2. ChangeOwnerKeyPeriod : passe de 1 MONTHS à 6 MONTHS — délai entre deux changements de clé owner multiplié par 6
    3. IdtyCreationPeriod : passe de 1 DAYS à 5 DAYS — délai entre deux créations d’identité multiplié par 5
3 Likes

Avec ma méthode, car je rencontre toujours un problème avec la méthode “officielle”, j’obtiens un autre hash :

builder@0389a8f4e8df:/build$ git branch
  network/gtest-1100
* runtime/gtest-1100
builder@0389a8f4e8df:/build$ git log -1
commit 17d0c8b97c7da96ca72fbb655463b7f0b7efb526 (HEAD -> runtime/gtest-1100, origin/runtime/gtest-1100)
Author: poka <poka@p2p.legal>
Date:   Sun Mar 1 23:23:11 2026 +0100

    docs: fix srtool blake2_256 extraction command with grep

commit 82dfc6b801b42e043a0c8241b24cbfd4b4dfd0bc
builder@0389a8f4e8df:/build$ /srtool/build 
🧰 Substrate Runtime Toolbox - srtool v0.18.3 🧰
              - by Chevdor -
info: override toolchain for '/build' set to '1.88.0-x86_64-unknown-linux-gnu'
info: component 'rust-std' for target 'wasm32-unknown-unknown' is up to date
info: component 'rust-src' is up to date
🏗  Building gtest-runtime as release using rustc 1.88.0 (6b00bc388 2025-06-23)
⏳ That can take a little while, be patient... subsequent builds may be faster.
   Since you have to wait a little, you may want to learn more about Substrate runtimes:
   https://docs.substrate.io/learn/architecture/
    Finished `release` profile [optimized] target(s) in 0.58s
✨ Your Substrate WASM Runtime is ready! ✨
✨ WASM  : runtime/gtest/target/srtool/release/wbuild/gtest-runtime/gtest_runtime.compact.wasm
✨ Z_WASM: runtime/gtest/target/srtool/release/wbuild/gtest-runtime/gtest_runtime.compact.compressed.wasm
Summary generated with srtool v0.18.3 using the docker image paritytech/srtool:1.88.0:
 Package     : gtest-runtime v1.0.0
 GIT commit  : 17d0c8b97c7da96ca72fbb655463b7f0b7efb526
 GIT tag     : runtime-1100
 GIT branch  : runtime/gtest-1100
 Rustc       : rustc 1.88.0 (6b00bc388 2025-06-23)
 Time        : 2026-03-02T13:06:33Z

== Compact
 Version          : gtest-1100 (duniter-gtest-1.tx1.au1)
 Metadata         : V14
 Size             : 3.16 MB (3308717 bytes)
 setCode          : 0x887dbc60298bb5eba24215a3c0cf90e124822a439998aaf849bcf9da05f0efe5
 authorizeUpgrade : 0xb5a2df88f3d27ab0933232f4d94a349ba3bf675ccef2a166e8839ba8f4d11caa
 IPFS             : QmSV2bYAQX441hVchPgQe4YY36FCjRzbfd8My9GUF2y2bX
 BLAKE2_256       : 0x1ae8b409f8e1fd11f013d5f3dd73ea6b97fae4e19cf2791580aa9f163c83a3f4
 Wasm             : runtime/gtest/target/srtool/release/wbuild/gtest-runtime/gtest_runtime.compact.wasm

== Compressed
 Version          : gtest-1100 (duniter-gtest-1.tx1.au1)
 Metadata         : V14
 Size             : 742.98 kB (760816 bytes)
 Compression      : 77.01%
 setCode          : 0x2cdca5ab77fc8afdeaea8297cdb03e77a50fabfb84d599713a5a9255aa300060
 authorizeUpgrade : 0x26c01e9b4311b6e8fd35bf8fd41d86207ae42618bde587c346ff73183c7f13b1
 IPFS             : QmZQvnwkFLor5dKuyxGbj1A7nWvDf57cXLhCgZNbG3otjG
 BLAKE2_256       : 0x87592e7a3f47558f2bb2194e236629bab8fbe894675a5d3e91662499c07c9cf8
 Wasm             : runtime/gtest/target/srtool/release/wbuild/gtest-runtime/gtest_runtime.compact.compressed.wasm
 BLAKE2_256       : 0x87592e7a3f47558f2bb2194e236629bab8fbe894675a5d3e91662499c07c9cf8

Ais-je raté qqch ?

Non c’est bien le bon hash, je ne sais pas ce qui te fait dire qu’il n’ai pas bon.

Tu n’as fait que la moitier de la procédure, tu dois récupérer le byte code de la premiage associé à la proposal et en vérifier le hash. Je n’ai pas donné le hash dans mon message (ne pas confondre avec le hash du code byte).

En effet, j’ai comparé le code byte avec le blake2_256 compressed obtenu avec ma compilation.


À l’étape 2, je ne sais pas où trouver ce fichier json. Je suppose que c’est le même contenu que ce que j’ai affiché plus haut, non ?

À l’étape 3. j’ai :

WASM_BYTES="0xa722bfc4eecc71e854d668c5700f99fd173c30d6bd29b39d685d162b05597ed3"
echo $WASM_BYTES | xxd -r -p | python3 -c \
  "import sys, hashlib; print('0x' + hashlib.blake2b(sys.stdin.buffer.read(), digest_size=32).hexdigest())"
0x0d72106233437ab0ba65b61044a5adc0b41c529362a2a8ae13dcbce647639e27

Du coup, je suis paumé en suivant la doc. La procédure est différente de la précédente.

Il vaut mieux lire la doc complète que j’ai donné en lien, ou bien lire le topic d’origine.

C’est ce que je fais, je suis la doc. J’utilise juste une autre méthode pour l’étape 1, car autrement j’ai l’erreur suivante :

duniter-v2s (runtime/gtest-1100)> cargo xtask release runtime build gtest
[…]
Digest: sha256:9902e50293f55fa34bc8d83916aad3fdf9ab3c74f2c0faee6dec8cc705a3a5d7
Status: Downloaded newer image for paritytech/srtool:1.88.0
sh: 7: cd: can't cd to /build🚀 Démarrage de srtool...

📁 Répertoire de travail: /build
🔧 Runtime: gtest
📄 Sortie: release/srtool_output_gtest.json
Error: Échec de la construction du runtime avec srtool

ok pull et réessai pour voir stp ?

Tu as copié le code byte hash au lieu de l’intégralité du code byte :slight_smile:

echo $WASM_BYTES | xxd -r -p | python3 -c \
  "import sys, hashlib; print('0x' + hashlib.blake2b(sys.stdin.buffer.read(), digest_size=32).hexdigest())"
poka@pokaBook duniter-v2s % bash tata
0x87592e7a3f47558f2bb2194e236629bab8fbe894675a5d3e91662499c07c9cf8

Il fait plusieur Mo donc bien coller ça dans un fichier, pas dans un prompt ça va buguer.
Je suis d’accords que c’est un peu bricolage, il faut faire une commande gcli qui automatise tout ça.

@technical-committee Je remarque que personne hormis @HugoTrentesaux n’a voté pour la proposual, y a il un soucis ?

Pas de changements notable. Je ne suis pas sûr que la vérification sur /build fonctionne, car le problème est dans le conteneur.
Cela-dit, mon problème est surement lié à SELinux. Il faut que je creuse dans cette direction.


Curieux, j’ai ça pour la proposition 8 :

N’étant pas authentifié via duniter-connect, Duniter Portal ne me propose pas la vue Technical commitee. Je suis sur le chemin /techcomm/proposals pour y avoir accès.

Je ne vois rien de curieux sur ta capture d’écran.

Il est normal que les hash affichés ne correspondent pas au hash du runtime code.

Le premier hash est le hash du call system.setCode lui-même, ce qu’on appelle le « hash du call » : c’est le hash blake2-256 du call encodé en SCALE, c’est-à-dire :
pallet index ++ call index ++ params.

Dans le cas de system.setCode :
• pallet index = 0
• setCode index = 2

Donc le hash du call system.setCode(code) est :
blake2-256(bin(0x0002<hex_code_bytes>))

Il faut convertir la représentation hexadécimale en binaire avant de hasher.

De la même façon, le hash du call parent (upgradeOrigin.dispatchAsRoot) :
• pallet index = 21
• dispatchAsRoot call index = 0

Donc le hash du call upgradeOrigin.dispatchAsRoot(system.setCode(code)) est :
blake2-256(bin(0x15000002<hex_code_bytes>))

Là aussi, il faut convertir la représentation hexadécimale en binaire avant de hasher.

Par contre, à l’avenir, il serait préférable d’utiliser system.authorizeUpgrade(codeHash) à la place de system.setCode(code). Cela présente plusieurs avantages :

  1. Un proposal avec system.setCode place l’intégralité du runtime code dans le proposal on-chain. Cela occupe plusieurs Mo de storage on-chain pour rien si jamais le proposal est refusé ou abandonné. À l’inverse, un proposal avec system.authorizeUpgrade ne contient que le hash du runtime code ; il est donc considérablement plus léger.
  2. Le call system.authorizeUpgrade, qui prend en paramètre le hash du runtime code, facilite la vérification : il n’est pas nécessaire de copier tout le bytecode hexadécimal pour effectuer les vérifications.

Une fois que le call system.authorizeUpgrade(codeHash) est exécuté (après un vote ayant atteint le seuil requis), n’importe qui peut appeler system.applyAuthorizedUpgrade(code) afin d’uploader le code complet et déclencher la mise à jour.

4 Likes

Ok je ne savais pas du tout, il faudra mettre à jour la doc dans ce cas :slight_smile:

1 Like

À l’époque où j’avais créé duniter-v2s, les call system.authorizeUpgrade(codeHash) et system.applyAuthorizedUpgrade(code) n’existaient pas dans Substrate. La seule option était system.setCode(code) à l’époque. C’est pour cela que j’avais indiqué ça dans la documentation d’origine. Si quelqu’un peut mettre à jour, ce serait chouette.

3 Likes

Je vois que la proposition de runtime upgrade n’a toujours que deux votes. Je suggère d’abandonner cette proposition et d’en soumettre une nouvelle en passant par system.authorizeUpgrade, afin de vous faire la main sur la meilleure manière de procéder. Ce sera également plus facile à vérifier pour les autres membres du CT.

Je publierais bien moi-même la proposition on-chain, mais il faut être membre du comité technique, donc je ne peux pas.

Voici une capture d’écran de la proposition à soumettre :

1 Like

Ok, j’en profite pour passer le seuil à 6 et non 5, pour faire les 2/3 des 8 membres du comité.

1 Like

Le boulot-euros :slight_smile: et puis j’ai suivi la procédure comme Moul, mais on n’a pas accès à l’intégralité du code byte que tu mentionnes ici.

Donc on ne peut pas vérifier.

1 Like