Guessing distance result before requesting evaluation

Asking the blockchain to evaluate distance result is a key part of identity creation process and membership renewal. As a spam prevention measure, some Ǧ1 are slashed in case of negative evaluation. The clients should only suggest the user to request distance evaluation when it knows the operation will result in a success. Thus clients should know distance result before the blockchain asks it to distance oracle. It is possible but cumbersome to evaluate distance result in the app because it means getting the whole web of trust and having an implementation. It would be easier to expose the result with a simple http endpoint which stays up to date with the web of trust and answers quickly to client requests. We have to set up an architecture for that.

I have a branch hugo/distance_precompute with an additional binary /distance-oracle/src/bin/distance_precompute.rs which runs in a cron to produce https://files.coinduf.eu/distance_precompute/latest_distance.json.

{
    "height": 3294347,
    "block": "0xc350d1f0711f396866c73f1430293ca7386427a3653216c180392ee233015d16",
    "referees_count": 1642,
    "member_count": 3400,
    "min_certs_for_referee": 6,
    "results": {
        "11660": 1607,
        "6549": 1556,
        "9892": 1444,
        ...
identity index → number of referees reached
        ...

This can be used for the moment to estimate distance before requesting evaluation.

Duniter panel now displays the result of distance computation:

Hi !

For now, this precomputed result is created by oracle nodes and served by a web server on these nodes.

Is it planned to serve the information through indexers ? As it is done for now, client softwares must know the URL of one precomputed distance file, but they would rather use indexers if the information is there.

For now, this is not even computed by all oracles. Only a script running on mine. This is currently a centralized architecture and I have no short term plan to make it easier to replicate. The binary comes from the hugo/distance-precompute branch.

As indexers are designed, I don’t think it is a good idea to add external data to it. It would be better to serve this directly on a part of Duniter RPC API. However, not all Duniter nodes would have this plugin installed (like not v1 Duniter nodes have transaction indexing, g1-monit, or wotwizard installed). So there should be a way to know which services are available where.

Client software must know a large list of URLs kinds (see Liste des endpoints topic). The same problem is valid for rpc endpoints, squid endpoints, datapod endpoints…

Il s’est passé beaucoup trop longtemps avant que je reprenne cette feature, mais la voilà bien améliorée puisque maintenant le résultat est disponible dans l’indexeur !

J’ai publié une image h30x/squid-graphile et h30x/squid-external-metrics actuellement utilisées dans mon docker compose. Vous pouvez faire ce requêtes sur mes deux indexeurs :

Évaluation de la règle pour une personne :

query DistancePrecompute {
  identities(condition: { name: "poka" }) {
    nodes {
      name
      distanceResults {
        nodes {
          accessibleReferees
          distancePrecompute {
            refereesCount
            computedOn {
              height
              hash
            }
          }
        }
      }
    }
  }
}
{
  "data": {
    "identities": {
      "nodes": [
        {
          "name": "poka",
          "distanceResults": {
            "nodes": [
              {
                "accessibleReferees": 4374,
                "distancePrecompute": {
                  "refereesCount": 4391,
                  "computedOn": {
                    "height": 182919,
                    "hash": "\\x8e3d5505d5fc44b360fc53d5f170afd81b93f953036d20a2885b2b0fa790fe1c"
                  }
                }
              }
            ]
          }
        }
      ]
    }
  }
}

Personnes qui ne respectent pas la règle :

query NotEnough {
  distancePrecomputes {
    nodes {
      refereesCount
    }
  }
  distanceResults(filter: {accessibleReferees: {lessThan: 3512}}, orderBy: ACCESSIBLE_REFEREES_DESC, first: 10) {
    nodes {
      accessibleReferees
      identity {
        name
        certReceived(filter: {isActive: {equalTo: true}}) {
          totalCount
        }
      }
    }
  }
}

{
  "data": {
    "distancePrecomputes": {
      "nodes": [
        {
          "refereesCount": 4391
        }
      ]
    },
    "distanceResults": {
      "nodes": [
        {
          "accessibleReferees": 3511,
          "identity": {
            "name": "gautz",
            "certReceived": {
              "totalCount": 3
            }
          }
        },
        {
          "accessibleReferees": 3511,
          "identity": {
            "name": "Chibouk",
            "certReceived": {
              "totalCount": 5
            }
          }
        },
        {
          "accessibleReferees": 3510,
          "identity": {
            "name": "Annoma",
            "certReceived": {
              "totalCount": 6
            }
          }
        },
        {
          "accessibleReferees": 3510,
          "identity": {
            "name": "Artix",
            "certReceived": {
              "totalCount": 1
            }
          }
        },
        {
          "accessibleReferees": 3510,
          "identity": {
            "name": "MoreauCatherine",
            "certReceived": {
              "totalCount": 5
            }
          }
        },
        {
          "accessibleReferees": 3509,
          "identity": {
            "name": "JeanDeLaTour",
            "certReceived": {
              "totalCount": 2
            }
          }
        },
        {
          "accessibleReferees": 3509,
          "identity": {
            "name": "Mao",
            "certReceived": {
              "totalCount": 4
            }
          }
        },
        {
          "accessibleReferees": 3508,
          "identity": {
            "name": "Lys2703",
            "certReceived": {
              "totalCount": 7
            }
          }
        },
        {
          "accessibleReferees": 3507,
          "identity": {
            "name": "Muuske",
            "certReceived": {
              "totalCount": 5
            }
          }
        },
        {
          "accessibleReferees": 3507,
          "identity": {
            "name": "mildred593",
            "certReceived": {
              "totalCount": 4
            }
          }
        }
      ]
    }
  }
}

Je vois déjà des trucs à ajuster pour le rendre plus utilisable, mais faites moi des retours avant qu’on merge et mette en prod pour tous ceux qui veulent, c’est le moment !

  • trouver un meilleur nom de que “distanceResults” qui sera probablement pris un jour par les évaluation de l’oracle (du type precomputeDistance ou externalDistance)
  • ajouter la quantité à atteindre pour les 80%
  • donner la possibilité de filtrer les identités ayant plus de cinq certifications reçues actives
  • conserver plusieurs résultats d’évaluation (faire attention au volume de données dans le futur)

Hello !

Oui je sais je m’y prend tard, mais je viens de tester les requêtes sur les nœuds indiqués et elles échouent. Je suppose que tu as mis à jour avec une image standard de l’indexer.

Je suis prêt à faire des tests et des retours pour Tikka quand tu le désireras. Il y a un vrai besoin de retrouver les fonctionnalités de Wot Wizard. Je les ai ajouté dans Tikka, mais le code inspiré de Cesium est lent et donne des résultats faux.

Un grand merci pour cette fonctionnalité prometteuse !

@vit Dunipod expose déjà les résultats de distance par membre. Chaque nœud Dunipod évalue la distance de tous les membres toutes les 2 heures (paramètre configurable par nœud). Ces données sont d’ailleurs affichées dans G1Data. Exemple pour mon compte : https://g1data-34abdc.pages.duniter.org/account/g1PHh7JNRWSfG6M8UP1rwcMRnFaAy1QPPjwHwW2Y5MBP2k4PJ?pod=g1pod2.elo.tf

Requête GraphQL permettant d’obtenir l’évaluation de distance d’un compte :

query DistanceParAdresse($address: String!) {
  identityByAccountId(accountId: $address) {
    index
    name
    accountId
    status
    distanceRule {
      perbill
      passes
      accessibleReferees
      effectiveAccessibleReferees
      refereeCount
      effectiveRefereeCount
      refereeThreshold
      minimumRequiredPerbill
      maxDepth
      sourceBlock
      sourceBlockHash
      computedAtUnixMs
      algorithmVersion
    }
  }
}

sourceBlock indique le numéro du bloc par rapport auquel la distance a été évaluée, et computedAtUnixMs donne la date et l’heure auxquelles le calcul a été effectué.

J’'héberge déjà deux pod qui calculent la distance toute les 2h:

https://g1pod.elo.tf/v1/graphql 
https://g1pod2.elo.tf/v1/graphql