Ğcli: Un client GVA en ligne de commande écrit en Rust

C’est frustrant d’être toujours uniquement coté serveur.

Si j’avais plus de temps j’aurais beaucoup aimé développer un client Ğ1 complet en Rust, mais je ne pourrais pas, car j’ai déjà beaucoup trop de travail coté Duniter :confused:

Alors dans l’espoir que quelqu’un développera un jour un client en Rust, j’ai pris une petite heure pour développer ce prototype :

J’espère que ce prototype en inspirera certains, en tout cas je suis dispo pour en expliquer le code à qui veut :smiley:

J’ai utilisé la crate graphql_client qui permet de vérifier à la compilation la validité de chaque requête graphql, et de générer automatiquement le typage des variables et de la réponse !!

Les requêtes sont écrites directement en language graphql dans le fichier gva_queries.gql.

Les options cli permettent déjà de choisir son serveur GVA, et de demander le DU courant et le solde d’un compte :

rust-gva-client 0.1.0
Client use GVA API of Duniter.

USAGE:
    gva-rust-client [OPTIONS] <SUBCOMMAND>

FLAGS:
    -h, --help       Prints help information
    -V, --version    Prints version information

OPTIONS:
    -s, --server <server>    GVA server url [default: https://g1.librelois.fr/gva]

SUBCOMMANDS:
    balance       Get account balance
    current-ud    Get current UD value
    help          Prints this message or the help of the given subcommand(s)

Ça m’a permis également de mesurer le temps que met mon serveur GVA pour répondre :

$ cargo run current-ud
    Finished dev [unoptimized + debuginfo] target(s) in 0.08s
     Running `target/debug/gva-rust-client current-ud`
The server responded in 225 ms.
The current UD value is 10.23 Ğ1 !

C’était rafraîchissant en tout cas, ça fait du bien de coder un truc simple pour une fois :blush:

10 J'aimes

Je pourrais peut-être m’y pencher, j’ai déjà codé quelques fonction clientes de GVA avec graphql_client et reqwest dans ĞMixer (demander les sources, l’historique, envoyer une tx).

3 J'aimes

C’est marrant que tu dises ça, parce que moi c’est l’inverse ! :grin:

J’en ai un peu marre de coder côté client, à cause des limitations de l’api, entre autres. Et te sachant seul côté serveur, je pensais à essayer de voir si je pouvais me mettre au Rust pour aider au développement de GVA et pourquoi pas, bien plus tard, du cœur. Mais bon, j’ai trop de projets en cours, à voir si j’arrive à ajouter l’apprentissage du Rust en plus, ou pas… :wink:

5 J'aimes

Justement je serai bientôt enfin prêt à accueillir des contributeurs sur Duniter, mais sur GVA uniquement, car c’est la seule partie suffisamment balisée et simple pour que je puisse accompagner dessus.

Si d’autres contributeurs arrivent à prendre en main le dev de GVA ça me permettrait de me concentrer sur les nombreux autres gros chantier de Duniter.

Alors évidemment je me rendrais dispo pour de l’accompagnement renforcé et des revus de code, surtout au début. L’idée est d’accompagner fortement au début puis de moins en moins au fur et à mesure :slight_smile:

4 J'aimes

Pour m’essayer un peu sur ce projet, j’ai réalisé une MR pour ajouter une requête sur le nombre de membres. J’ai quelques remarques et questions :

  1. Les macros #[derive(GraphQLQuery)] et #[graphql(schema_path, query_path)] sont très pratiques, mais il est un peu difficile de savoir les noms des structs et enums générés. Où est-ce documenté ?
  2. Le schéma est défini en format .gql, ce qui ne fait pas partie des formats proposés par https://g1.librelois.fr/gva. Comment est-ce qu’on obtient ce format ? (pour l’instant j’ai ajouté une entrée manuellement, mais je suppose qu’il y a une manière automatique de faire)
  3. Pourquoi le schéma utilisé est-il légèrement différent de celui disponible sur ton interface web? Par exemple, dans le QueryRoot, il manque la ligne currentBlock sur le client. (c’est celle que j’ai ajouté)

En tout cas, joli travail, GVA va nous simplifier la vie à tous, j’espère que l’on pourra accueillir des contributeurs sérieux sur ce chantier !

hugo@squid:~/dev/gva-rust-client$ ./target/debug/gcli members-count
The server responded in 523 ms.
There is currently 2876 members in Ğ1 WoT!
2 J'aimes

Alors en fait le schéma est au format SDL (Schéma Description Langage).
Oui il est généré automatiquement à partir du code de GVA :slight_smile:

Parce qu’il n’est pas à jour à cause de Cargo.lock, pour maj le scéma :

cargo update -p duniter-gva-gql
1 J'aime

Je viens de baptiser le projet ğcli :smiley:

Je ne pourrais pas y consacrer du temps significatif, mais j’y ajouterai une commande de temps en temps selon mes besoins et mes envies.

Et j’invite bien sur tous ceux qu le souhaitent à y implémenter les commandes dont ils ont besoin, c’est un client collaboratif :blush:

Je peux former @HugoTrentesaux, @tuxmain et qui veut sur ğcli, c’est un petit projet très simple :slight_smile:

Tout ce que je demande c’est que toute nouvelle commande soit obligatoirement testée !

«Si c’est pas testé, c’est pas mergé». Et ce sera vrai aussi pour ceux qui voudraient contribuer à GVA :wink:

Ce projet n’a pas d’objectif particulier, il permettra ce que ses contributeurs en feront.

4 J'aimes

Liberté, ğcli ton nom !

5 J'aimes

J’ai commencé à faire une commande pour afficher l’historique des transactions.

Je ne sais pas encore comment intégrer la pagination dans l’interface, c’est peu pratique de recopier le curseur dans la commande pour chaque page. Sinon un truc interactif qui avance d’une page à l’appui d’une touche ?

3 J'aimes

Oui par exemple :slight_smile:

EDIT: Pour la gestion interactive du terminal je te recommande termion.

Le mieux est de pouvoir permettre aussi le retour à la page précédente :slight_smile:

1 J'aime

En fait l’affichage des transactions est très complexe, on ne peut pas se contenter d’écrire « X : envoyé/reçu Y Ğ1 », il faut gérer les conditions et les cas où on s’envoie à soi-même…

Une même transaction peut-elle apparaître à la fois dans sent et dans received dans GVA et BMA ? Comment Duniter choisit ?

1 J'aime

Non elle ne peut pas, un compte est inscrit comme receiver uniquement s’il n’est pas issuer, c’est fait ici :

Dans Duniter 1.9, le code javascript qui fourni l’historique des transactions n’existe plus, il a été migré en Rust. Donc BMA se base sur ce même code Rust donc elle fournit les mêmes données que GVA.

EDIT: cela implique notamment qu’une transaction de change n’a pas de destinataire, ce qui est cohérent :slight_smile:

2 J'aimes

@tuxmain attention il faut que tu utilises both et pas sent ou received !

En effet supposons que tu veuilles afficher les 10 dernières transactions d’un compte.
Tu ne peux pas prendre les 5 dernières émises et les 5 dernières reçues ça ne fonctionne pas.
Un compte peut très bien avoir émis 8 transactions sur les 10 dernières et reçus 2, et vice-versa, où n’importe quelle proportion entre les deux.

Il faut donc fusionner les transactions émises et reçus dans ure seule liste, la triée par date d’écriture, puis tronquer à la taille de la page voulue. C’est exactement ce que fait both coté serveur pour vous éviter d’avoir à coder cette logique côté client !

1 J'aime

Oui c’est ce que j’ai fait sur Ḡecko et jaklis, pourquoi ne pas avoir fait ça aussi pour les transcations en mempool ? Un both ? C’est moins utile peut être ?

Il n’y a aucune raison, je n’y ai juste pas pensé, car c’est surtout pour la pagination que j’ai pensé both. Un contributeur pourra rajouter ça à GVA si c’est souhaité :slight_smile:

1 J'aime

3 messages ont été scindés en un nouveau sujet : Comment faut-il afficher les transactions complexes?

Pour le moment j’ai ça :

2020-10-17T08:16:16+00:00  #365512
8AURKq5gWeESdPzgqL2fJYFoJv89X2wiSsWbx8Am2W3w  + 2 Ğ1  Commentaire

2020-10-17T12:24:07+00:00  #365694
SIG(9oca3YvBuJBYdK5tdJESbT4tPVfxkDBtjGetU8jnkRpp)  - 204.6 Ğ1  Commentaire
SIG(45GfjkWCWQhJ3epJVGC2NSg1Rcu4Ue1vDD3kk9eLs5TQ)  - 123 Ğ1
Total: 317.6 Ğ1

Pour les txs reçues on affiche la liste des issuers.

Pour les txs envoyées on affiche la liste des scripts d’outputs. On ignore les outputs SIG(issuer). Les txs de change apparaissent donc vides. S’il y a plusieurs outputs, on affiche le total en bas.

Le commentaire est écrit à la fin de la première ligne d’outputs/issuers. Il y a une option pour afficher en DU.

Est-ce que vous préféreriez une forme tabulaire, comme dans Silkaj ? On pourrait aussi mettre des couleurs (rouge/vert pour dépense/gain, gris pour le numéro de bloc). Ou aussi afficher conjointement Ğ1 et DU.

Merci @tuxmain :slight_smile:

Puisque tu demandes des avis, voici le mien :

A titre perso je préférerai un tableau avec une vue condensée sur une ligne pour chaque tx. Et une possibilité de voir plus en détail une seule tx si on en a besoin :slight_smile:

3 J'aimes

@tuxmain j’ai hâte que tu intègres la gestion de la pagination de l’historique à ḡcli, parce-que dans Ḡecko j’ai des artefacts étrange au bout de plusieurs pages, je voudrais être sûr que le soucis ne vient pas de GVA …

2 J'aimes

@tuxmain je viens d’ajouter les conventions du projet dans CONTRIBUTING :slight_smile:

Le plus important est surtout de bien découpler l’affichage de la logique en créant un type AccountHistoryView qui contiendra toutes les données à afficher et un type AccountHistoryState qui contiendra «l’état» courant de l’application.

L’idée étant que les actions utilisateur (appui sur urne touche) mettent à jour le State uniquement. Puis que séparément, le State met à jour la View.

Ainsi tu peux injecter la logique dans des fonctions pure, donc testable :slight_smile:

Aussi pense bien à découper en plusieurs fichiers. Prends de temps de faire un code lisible, ça ne sert à rien de se presser :wink:

2 J'aimes