Très peu de noeuds calculant sur gtest/ bug d’exclusion


#82

Je ne sais pas quels outils tu utilises, mais je t’invite à créer les clés en faisant des opérations sur courbes élliptiques (style HD wallet) que tu passer par scrypt avec seed + mot de passe (justement parcequ’il est long à calculer pour empécher les bruteforce)


#83

Je viens de réessayer avec la 1.6.24 from scratch et ça plante idem avec les données de ce jour
2018-06-05T13:19:47+02:00 - error: Error: ruleToBeKickedArePresent at Function.checkBlock (/opt/duniter/app/lib/blockchain/DuniterBlockchain.js:170:19)

@isawien45
tu as fait un update vers la 1.6.24 depuis la 1.6.23 lorsque la 1.6.23 était déjà synchronisé ?

Merci


#84

@aguy
Oui la version 1.6.23 etait synchro quand j’ai fait l’update.

fyi : j’ai installé sur mon noeux le module currency-monitor. J’ai pu donc voir ou en était mon inscription. j’ai 2 de dispo, 2 autre à partir de 17h20 et la dernière 22h.


#85

J’utilise mon propre générateur. En gros j’ai pompé les sources depuis le repo de libSodium, que j’ai intégrées en un seul gros générateur en multithread. Ça pulse, je me suis bien amusé. :slight_smile: L’idée à la base était de transformer ça en opencl, je le ferai peut-être quand j’aurai le temps. Mais rien que la génération de seed risque d’être rigolote à tranformer… pour scrypt c’est encore une autre histoire, avec aussi un peu plus de défi en terme de mémoire.

Et pour une utilisation avec silkaj seul, le seed suffit et la courbe elliptique sécurise déjà le truc. Le fait d’avoir scrypt par-dessus ne rajoute en fait pas grand-chose - seulement le fait que c’est plus facilement mémorisable qu’un seed (parce que là, même avec Loki et compagnie, bon courage !).

@Melua Effectivement, c’est en fait assez chaud ! J’ai essayé avec ^[Mm][eE3][Ll][Uu][aA4] et je n’ai trouvé qu’une seule adresse pour l’instant sur 4 cœurs de mon vieil Athlon :stuck_out_tongue: .


#86

Ok,

Je confirme au cas où cela puisse intéresser les devs:

  • noeud monter from scratch plante à la synchro à 99% “ruleToBeKickedArePresent…”
  • noeud 1.6.23 synchronisé updated to 1.6.24: fonctionne bien

:wink:


#87

Il y a plusieurs façons de se synchroniser :

  1. on peut le faire en ciblant des nœuds différents, ou a des instants différents
  2. en version rapide
  3. en version lente (vérification stricte)
  4. le faire depuis un nœud propre
  5. le faire depuis un nœud déjà synchronisé, donc dans un état qui dépend de 1,2,3,4.

Et donc chaque synchro est particulière. Les conditions ne sont (presque) jamais les mêmes.

Oui ça m’intéresse, d’autant que les synchros en 1.6 sont particulièrement longues sur la Ğ1 et la Ğ1-Test.


#88

Bon je ne synchronise pas non plus, par contre j’ai une stack, cela t’intéresse t’il ?


#89

Tu peux toujours la poster, ça peut m’aider moi comme les autres utilisateurs qui nous lisent.


#90
2018-06-05T15:38:45+02:00 - error: Error: Service not found
    at /opt/duniter/node_modules/nat-upnp/lib/nat-upnp/device.js:58:23
    at respond (/opt/duniter/node_modules/nat-upnp/lib/nat-upnp/device.js:27:5)
    at /opt/duniter/node_modules/nat-upnp/lib/nat-upnp/device.js:42:7
    at Parser.<anonymous> (/opt/duniter/node_modules/xml2js/lib/xml2js.js:199:18)
    at Parser.emit (events.js:160:13)
    at SAXParser.saxParser.onclosetag (/opt/duniter/node_modules/xml2js/lib/xml2js.js:183:24)
    at emit (/opt/duniter/node_modules/sax/lib/sax.js:624:35)
    at emitNode (/opt/duniter/node_modules/sax/lib/sax.js:629:5)
    at closeTag (/opt/duniter/node_modules/sax/lib/sax.js:889:7)
    at SAXParser.write (/opt/duniter/node_modules/sax/lib/sax.js:1436:13)
    at Parser.exports.Parser.Parser.parseString (/opt/duniter/node_modules/xml2js/lib/xml2js.js:211:31)
    at Parser.parseString (/opt/duniter/node_modules/xml2js/lib/xml2js.js:6:61)
    at Request._callback (/opt/duniter/node_modules/nat-upnp/lib/nat-upnp/device.js:39:12)
    at Request.self.callback (/opt/duniter/node_modules/request/request.js:188:22)
    at Request.emit (events.js:160:13)
    at Request.<anonymous> (/opt/duniter/node_modules/request/request.js:1171:10)
    at Request.emit (events.js:160:13)
    at IncomingMessage.<anonymous> (/opt/duniter/node_modules/request/request.js:1091:12)
    at Object.onceWrapper (events.js:255:19)
    at IncomingMessage.emit (events.js:165:20)
    at endReadableNT (_stream_readable.js:1101:12)
    at process._tickCallback (internal/process/next_tick.js:152:19)

2018-06-05T15:46:19+02:00 - error:  Error: ruleInputIsAvailable
    at Function.checkBlock (/opt/duniter/app/lib/blockchain/DuniterBlockchain.js:176:19)
    at <anonymous>


2018-06-05T15:56:48+02:00 - error: WS2P >>> >>> WS ERROR: INCORRECT_PUBKEY_FOR_REMOTE
2018-06-05T15:56:48+02:00 - error: WS2P >>> >>> WS ERROR: REJECTED_PUBKEY_OR_INCORRECT_ASK_SIGNATURE_FROM_REMOTE
2018-06-05T15:56:48+02:00 - error: WS2P >>> >>> WS ERROR: REJECTED_PUBKEY_OR_INCORRECT_ASK_SIGNATURE_FROM_REMOTE


#91

L’UPnP semble activé sur ton nœud, pourtant n’est visiblement pas disponible chez toi.

Pour le ruleInputIsAvailable, je ne suis pas étonné car @jytou fais des stress-tests :slight_smile:


#92

Pour mémoire, je vais ici mettre les informations de débogage que je trouve.

D’abord il faut voir que le membre qui pose problème est BubEHcMEAkC5trxru2D9GAkRsdFbLMQ1Mbgya5ZyndN7, je le sais en mettant un point d’arrêt sur les lignes :

Puis en lançant la synchro dans VS Code en mode debug. Regarder la variable toKick montre qu’il s’agit de BubEHc[...] qui est marqué comme “à sortir”, mais qui n’est pas présent dans le bloc dans la section Excluded. D’où l’erreur "ruleToBeKickedAreNotPresent`, règle qui stipule qu’un membre qui doit sortir est bien explicitement sorti dans le bloc.

Si la règle se déclenche, c’est que ce n’est pas le cas et donc le bloc est marqué comme invalide. Maintenant reste à voir pourquoi ce membre est marqué comme “à sortir” et qu’il ne l’est pas dans le bloc.


#93

Cela expliquerai t’il le fait que le bloc 191680 soit vu comme incorrect ?

2018-06-05T16:44:12+02:00 - info: Fork resolution: 48 potential block(s) found...
2018-06-05T16:44:12+02:00 - info: Fork resolution: block #191680-00032523 is known as incorrect. Skipping.
2018-06-05T16:44:12+02:00 - debug: Suite -> 191724-00014391 missing block#191680-00032523
2018-06-05T16:44:12+02:00 - info: Fork resolution: block #191680-00032523 is known as incorrect. Skipping.
2018-06-05T16:44:12+02:00 - debug: Suite -> 191724-0001388C missing block#191680-00032523
2018-06-05T16:44:12+02:00 - info: Fork resolution: block #191680-00032523 is known as incorrect. Skipping.
2018-06-05T16:44:12+02:00 - debug: Suite -> 191721-000058E9 missing block#191680-00032523
2018-06-05T16:44:12+02:00 - info: Fork resolution: block #191680-00032523 is known as incorrect. Skipping.
2018-06-05T16:44:12+02:00 - debug: Suite -> 191715-00026283 missing block#191680-00032523
2018-06-05T16:44:12+02:00 - info: Fork resolution: block #191680-00032523 is known as incorrect. Skipping.
2018-06-05T16:44:12+02:00 - debug: Suite -> 191709-0006E932 missing block#191680-00032523
2018-06-05T16:44:13+02:00 - info: Fork resolution: block #191680-00032523 is known as incorrect. Skipping.
2018-06-05T16:44:13+02:00 - debug: Suite -> 191704-0003140F missing block#191680-00032523

#94

Ensuite, j’utilise un outil que je suis en train de développer et qui permet d’extraire « l’histoire » d’une clé, et les grandes étapes qui l’attendent.

D’abord un outil un peu “bas niveau” qui affiche les entrées de la clé dans les index :

~/dev/duniter$ bin/duniter dump table i_index pub=BubEHcMEAkC5trxru2D9GAkRsdFbLMQ1Mbgya5ZyndN7 
┌────────┬──────────────┬──────────────────────────────────────────────┬──────────────────────────────────────────────────────────────────┬──────────────────────────────────────────────────────────────────────────────────────────┬────────────────────────────────────────────────────────────────────────┬─────────────────────────────────────────────────────────────────────────┬────────┬───────────┬──────┬─────────┐
│ op     │ uid          │ pub                                          │ hash                                                             │ sig                                                                                      │ created_on                                                             │ written_on                                                              │ member │ wasMember │ kick │ wotb_id │
├────────┼──────────────┼──────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────┼────────┼───────────┼──────┼─────────┤
│ CREATE │ ji_emme_test │ BubEHcMEAkC5trxru2D9GAkRsdFbLMQ1Mbgya5ZyndN7 │ D56188047FC8D5E9D6D73F926CD826838E3C8E8C97F173CD958418F0B5EC9569 │ LOKD5XnteuUyr8RDuOZyh/y2/Rs/HVm05qt0tdGewVLgsj15esuchfemN2XKAgiSL8KTC8rvAB4EAsPI2AWMBg== │ 91886-0000973FB47B628301D6E9137D0D3C573B8AE2B1A76EDDF099E5D50F04D3B6CD │ 94549-00006D6A7F0FFCDFCEE98AD42091D5DDBB7BADBD824405540541E01A2AE3FC27  │ 1      │ 1         │ 0    │ 44      │
├────────┼──────────────┼──────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────┼────────┼───────────┼──────┼─────────┤
│ UPDATE │ NULL         │ BubEHcMEAkC5trxru2D9GAkRsdFbLMQ1Mbgya5ZyndN7 │ NULL                                                             │ NULL                                                                                     │ NULL                                                                   │ 134225-002C4111A00503ACAFCA84505E4EEB2C80115E41663E0A9CABEB15612F122D9B │ NULL   │ NULL      │ 1    │ NULL    │
├────────┼──────────────┼──────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────┼────────┼───────────┼──────┼─────────┤
│ UPDATE │ NULL         │ BubEHcMEAkC5trxru2D9GAkRsdFbLMQ1Mbgya5ZyndN7 │ NULL                                                             │ NULL                                                                                     │ NULL                                                                   │ 134225-002C4111A00503ACAFCA84505E4EEB2C80115E41663E0A9CABEB15612F122D9B │ 0      │ NULL      │ 0    │ NULL    │
└────────┴──────────────┴──────────────────────────────────────────────┴──────────────────────────────────────────────────────────────────┴──────────────────────────────────────────────────────────────────────────────────────────┴────────────────────────────────────────────────────────────────────────┴─────────────────────────────────────────────────────────────────────────┴────────┴───────────┴──────┴─────────┘

~/dev/duniter$ bin/duniter dump table m_index pub=BubEHcMEAkC5trxru2D9GAkRsdFbLMQ1Mbgya5ZyndN7 
┌────────┬──────────────────────────────────────────────┬────────────────────────────────────────────────────────────────────────┬─────────────────────────────────────────────────────────────────────────┬────────────┬────────────┬────────────┬────────────┬─────────┬────────────┬──────────────┐
│ op     │ pub                                          │ created_on                                                             │ written_on                                                              │ expires_on │ expired_on │ revokes_on │ revoked_on │ leaving │ revocation │ chainable_on │
├────────┼──────────────────────────────────────────────┼────────────────────────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────┼────────────┼────────────┼────────────┼────────────┼─────────┼────────────┼──────────────┤
│ CREATE │ BubEHcMEAkC5trxru2D9GAkRsdFbLMQ1Mbgya5ZyndN7 │ 94317-0000E10FB21B5EEBBCFB51D267873B5EFB1146D398C5B676E50BBBFB0355D961 │ 94549-00006D6A7F0FFCDFCEE98AD42091D5DDBB7BADBD824405540541E01A2AE3FC27  │ 1518222368 │ NULL       │ 1524533888 │ NULL       │ 0       │ NULL       │ 1512997756   │
├────────┼──────────────────────────────────────────────┼────────────────────────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────┼────────────┼────────────┼────────────┼────────────┼─────────┼────────────┼──────────────┤
│ UPDATE │ BubEHcMEAkC5trxru2D9GAkRsdFbLMQ1Mbgya5ZyndN7 │ 94317-0000E10FB21B5EEBBCFB51D267873B5EFB1146D398C5B676E50BBBFB0355D961 │ 134225-002C4111A00503ACAFCA84505E4EEB2C80115E41663E0A9CABEB15612F122D9B │ NULL       │ 1518222711 │ NULL       │ NULL       │ NULL    │ NULL       │ NULL         │
├────────┼──────────────────────────────────────────────┼────────────────────────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────┼────────────┼────────────┼────────────┼────────────┼─────────┼────────────┼──────────────┤
│ UPDATE │ BubEHcMEAkC5trxru2D9GAkRsdFbLMQ1Mbgya5ZyndN7 │ 94317-0000E10FB21B5EEBBCFB51D267873B5EFB1146D398C5B676E50BBBFB0355D961 │ 169591-0000118C96D3BE4FBA485F546ADCA612F84F592ED60D1A8456C43E9668116319 │ NULL       │ NULL       │ NULL       │ 1524533955 │ NULL    │ NULL       │ NULL         │
└────────┴──────────────────────────────────────────────┴────────────────────────────────────────────────────────────────────────┴─────────────────────────────────────────────────────────────────────────┴────────────┴────────────┴────────────┴────────────┴─────────┴────────────┴──────────────┘

Une première chose qui attire mon œil c’est que dans l’i_index, il y a 2 entrées modifiant le champ “kick” au même bloc : l’un qui le passe à true (cela veut dire : il faut sortir ce membre, pour une bonne raison), l’autre le passe à false (pour dire : c’est bon, il est sorti).

Ce qui est très curieux car j’ai souhaité faire en sorte que justement ces 2 lignes soient écrites par des blocs différents ! De façon à être certain qu’il n’y ai pas d’ambiguïté sur quelle ligne avait précédence sur l’autre : d’abord un bloc marque le membre comme a sortir, en vertu des enregistrements de “clôture” du bloc, puis le bloc suivant marque le membre comme sorti s’il est présent dans le champ Excluded de ce bloc, et il le doit (cf. la règle ruleToBeKickedArePresent).

Mais là … les 2 lignes en même temps … ça semble être une anomalie.

Autre point qui attire mon œil : l’identité est censée expirer au timestamp 1518222368, or le bloc 134224 a pour timestamp précisément 1518222368. C’est un cas à la marge et je vais vérifier que ce n’est pas la cause du problème.


#95

Oui tout à fait.


#96

Donc en effet c’était bien le cas à la marge : le bug se situait dans la synchro rapide, qui aurait dû s’arrêter au bloc 134224 pour marquer le membre comme à sortir, mais qui à la place attendait le bloc 134225 générant une double écriture sur un même bloc (kick: true et kick: false) qui elle-même amène une ambiguïté dans l’état des données.

C’est trivial à corriger, je vais faire une version d’ici ce soir. Je vais tout de même vérifier qu’il n’y a pas d’impacts sur la Ğ1.


#97

@cgeek ok encore un point interprétable du protocole, cela signifie t’il que pour duniter-ts un membre n’est pas exclu lors du 1er bloc ou il expire mais seulement lors du bloc d’après ?

Pour être plus clair :
imaginons qu’un membre expire a une date t1.
Je pensais qu’il expirai alors dans le premier block qui atteint ou dépasse t1. Tu semble dire qu’il expire en réalité dans le bloc suivant le 1er block qui atteint ou dépasse t1 ? Si oui pourquoi ? Pourquoi ne pas faire expirer le membre directement dés le 1er block qui atteint ou dépasse t1 ?


#98

Non non c’est la synchro qui n’implémentait pas correctement celui-ci. Le protocole ne laisse pas d’ambiguïté sur ce point.

Oui c’est bien le cas. Je suis parti du principe qu’on actait l’avancé du temps à la sauvegarde, c’est donc une fois le bloc interprété que j’acte le temps et fait périmer les documents présents en blockchain + piscine.

Ici l’i_index voit passer un kick: true une fois le bloc 134224 interprété et traité (son contenu).

Oui il est explicitement retiré dans le bloc suivant à travers le champ Excluded, c’est à ce moment là qu’il devient véritablement non-membre.

Mais d’ailleurs acter le temps à la fin du bloc reçu ou au début du suivant revient strictement au même, vu qu’il s’agit d’un temps prédéterminé. Mais autant le faire avancer à la réception du bloc, ça permet de gagner du temps plutôt que d’attendre (pour rien !) l’arrivée du bloc suivant.


J’en profite pour rappeler les étapes provoquées par la réception d’un bloc :

  • Etape 1 : génération des écritures locales pour l’index, déductibles directement par simple lecture du bloc (= fonction localIndex() dans Duniter)
  • Etape 2 : augmentation des écritures locales avec des données provenant de la blockchain (timestamps correspondants aux blockstamps des certifications, adhésions, identités ou transactions présentes dans le bloc, calcul du DU théorique pour ce bloc, …) (= fonction completeGlobalScope() dans Duniter)
  • Etape 3 : vérification de la cohérences des écritures locales avec celles globales (= la blockchain) vis-à-vis des règles du protocole (= suite de tests dans la fonction checkBlock de Duniter)
  • Etape 4 : génération d’écritures dites « de clôture » qui augmentent encore les écritures locales : création des sources de DU, faire expirer les adhésions et certifications, et par conséquent marquer les membres éventuellement à exclure, générer les révocations implicites, …) (= fonction generateIndexes() dans Duniter, dans le cadre de saveBlockData())

#99

Ben pour moi c’est justement une interprétation. On peut aussi partir du principe que l’avancée du temps est actée dés le début de l’application du bloc plutôt qu’a la fin.


#100

Tu parles peut-être de liberté d’implémentation là, mais c’est différent. Le protocole ne me semble pas ambigu quant aux définitions (ici, ce qui est nommé HEAD) et la suite des opérations à appliquer dessus.


#101

@jytou @aguy @isawien45

La version 1.6.25 en pré-release est disponible. Vous pouvez l’essayer sur ĞTest, et je valide aussi sur la Ğ1 avant de passer en statut release.