Nous avons une discussion sur #195 avec @cgeek, je pense qu’elle peut être intéressante pour ceux qui veulent avoir des repères sur les concepts de réseau, client, runtime, specs… Je vais essayer de poser quelques bases ici que j’aurais apprécié lire clairement dans la doc et qui ne m’étaient pas apparues clairement dans le post d’@elois Vocabulaire de base pour comprendre Duniter-v2s (lecture fortement recommandée pour tous).
Client
version elois
Le client est à la fois la “machine virtuelle” qui exécute le runtime, et le logiciel qui assura la connexion avec l’extérieur (couche p2p, API RPC, oracle de distance, keystore…). Le client inclut un runtime “natif” (mais on ne l’utilise pas sauf exception), plusieurs specs (par exemple duniter --chain=dev
, duniter --chain=gdev
pour un client compilé avec la feature gdev
), cf le super post État des lieux des différentes chaînes.
Runtime
version elois
C’est à la fois un élément de l’état (state) en tant que “donnée binaire” et à la fois la fonction de transition d’état (state transition) interprétée en webassembly et exécutée à chaque bloc par le client pour passer d’un état au suivant. Elle peut être modifiée par la méthode system.setCode(runtime)
, elle-même faisant partie du runtime.
Spec
version hugo
La définition d’elois est très bien . Pour plus d’infos, cf le code (je cite en simplifiant) :
pub struct ChainSpec {
client_spec: ClientSpec,
genesis: GenesisSource,
}
struct ClientSpec {
name: String,
id: String,
chain_type: ChainType,
boot_nodes: Vec<MultiaddrWithPeerId>,
protocol_id: Option<String>,
fork_id: Option<String>,
properties: Option<Properties>,
code_substitutes: BTreeMap<String, Bytes>,
}
enum GenesisSource {
File(PathBuf),
Binary(Cow<'static, [u8]>),
Storage(Storage),
GenesisBuilderApi(GenesisBuildAction, Vec<u8>),
}
Réseau
C’est la notion que me manquait au début. C’est à la fois simple car intuitif, et complexe car plein de concepts entrent en jeu.
Un réseau blockchain, c’est un ensemble de machines connectés ensemble qui exécutent le même code (runtime) en même temps. Un réseau peut avoir plusieurs clients différents. Ces clients peuvent être légèrement différents (version différente, architecture différente) ou même radicalement différents (autre implémentation dans un autre langage).
Le runtime d’un réseau peut évoluer au cours du temps (blocs de numéro croissant) lors des runtime upgrades. Ça reste le même réseau, mais toutes les machines se sont mises d’accord en même temps de changer leur fonction de transition d’état.
Une chose qui a pu vous perturber est qu’on a utilisé des noms contre-intuitifs pour les différents réseaux gdev. Par exemple gdev-700
et gdev-800
étaient des réseaux différents alors que gdev-801
est juste un autre nom pour le réseau gdev-800
qui a juste connu un runtime upgrade. On aurait pu (et on pourra à l’avenir) les appeler gdev-a
, gdev-b
etc pour les réseaux successifs et comme ça gdev-802
désignerait uniquement un runtime, et pas un réseau. Le même runtime pourrait être exécuté sur plusieurs réseaux.
subtilité
En fait, tous les clients n’exécutent pas forcément exactement le même runtime. Certains peuvent se risquer à exécuter un runtime différent (par exemple runtime natif plutôt que webassembly) du moment que la transition d’état est exactement la même. Mais c’est très découragé parce que si on trouve un résultat différent des autres, ils peuvent nous bannir ><
Voilà, j’espère que ça peut vous aider à vous y retrouver. En tout cas, même nous on est un peu perdus quand il s’agit de choisir le modèle de release >< (cf #195 pour plus de discussions).