# Can an identity have no associated account?

**URL:** https://forum.duniter.org/t/can-an-identity-have-no-associated-account/12824
**Category:** Indexers
**Created:** [24 December 2024 14:32 UTC](https://forum.duniter.org/t/can-an-identity-have-no-associated-account/12824 "2024-12-24T14:32:35Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![poka](https://forum.duniter.org/user_avatar/forum.duniter.org/poka/32/6827_2.png) [@poka](https://forum.duniter.org/u/poka)
#### Post date: [24 December 2024 14:32 UTC](https://forum.duniter.org/t/can-an-identity-have-no-associated-account/12824/1 "2024-12-24T14:32:35Z")

</div>

```auto
{
  identity(where: {accountId: {_isNull: true}}) {
    accountId
    account {
      createdOn
    }
    name
    status
    createdInId
    createdOn
    expireOn
    firstEligibleUd
    id
    index
    lastChangeOn
  }
}

```

→

```auto
{
  "data": {
    "identity": [
      {
        "accountId": null,
        "account": null,
        "name": "0000115597-0c545-000002",
        "status": "REMOVED",
        "createdInId": "0000115597-0c545-000002",
        "createdOn": 115597,
        "expireOn": 129997,
        "firstEligibleUd": null,
        "id": "0000115597-0c545-000002",
        "index": 14574,
        "lastChangeOn": 115597
      },
      {
        "accountId": null,
        "account": null,
        "name": "ChristCosmic",
        "status": "REMOVED",
        "createdInId": "0000069295-23123-000002",
        "createdOn": 69295,
        "expireOn": 945902,
        "firstEligibleUd": null,
        "id": "0000069295-23123-000002",
        "index": 14573,
        "lastChangeOn": 69302
      },
      {
        "accountId": null,
        "account": null,
        "name": "tuxmaintest01",
        "status": "REMOVED",
        "createdInId": "0001317492-bfa3d-000002",
        "createdOn": 1317492,
        "expireOn": 2194183,
        "firstEligibleUd": null,
        "id": "0001317492-bfa3d-000002",
        "index": 14575,
        "lastChangeOn": 1317583
      },
      {
        "accountId": null,
        "account": null,
        "name": "0002192620-ba24f-000002",
        "status": "REMOVED",
        "createdInId": "0002192620-ba24f-000002",
        "createdOn": 2192620,
        "expireOn": 2207020,
        "firstEligibleUd": null,
        "id": "0002192620-ba24f-000002",
        "index": 14578,
        "lastChangeOn": 2192620
      },
      {
        "accountId": null,
        "account": null,
        "name": "0002255022-81425-000002",
        "status": "REMOVED",
        "createdInId": "0002255022-81425-000002",
        "createdOn": 2255022,
        "expireOn": 2269422,
        "firstEligibleUd": null,
        "id": "0002255022-81425-000002",
        "index": 14579,
        "lastChangeOn": 2255022
      },
      {
        "accountId": null,
        "account": null,
        "name": "0002318658-7d776-000002",
        "status": "REMOVED",
        "createdInId": "0002318658-7d776-000002",
        "createdOn": 2318658,
        "expireOn": 2333058,
        "firstEligibleUd": null,
        "id": "0002318658-7d776-000002",
        "index": 14581,
        "lastChangeOn": 2318658
      },
      {
        "accountId": null,
        "account": null,
        "name": "d0p1",
        "status": "REMOVED",
        "createdInId": "0001562241-75850-000002",
        "createdOn": 1562241,
        "expireOn": 2451624,
        "firstEligibleUd": null,
        "id": "0001562241-75850-000002",
        "index": 14576,
        "lastChangeOn": 1575024
      },
      {
        "accountId": null,
        "account": null,
        "name": "0002731824-23863-000002",
        "status": "REMOVED",
        "createdInId": "0002731824-23863-000002",
        "createdOn": 2731824,
        "expireOn": 2746224,
        "firstEligibleUd": null,
        "id": "0002731824-23863-000002",
        "index": 14582,
        "lastChangeOn": 2731824
      },
      {
        "accountId": null,
        "account": null,
        "name": "0002761399-cbfb2-000002",
        "status": "REMOVED",
        "createdInId": "0002761399-cbfb2-000002",
        "createdOn": 2761399,
        "expireOn": 2775799,
        "firstEligibleUd": null,
        "id": "0002761399-cbfb2-000002",
        "index": 14583,
        "lastChangeOn": 2761399
      },
      {
        "accountId": null,
        "account": null,
        "name": "0002920654-af135-000002",
        "status": "REMOVED",
        "createdInId": "0002920654-af135-000002",
        "createdOn": 2920654,
        "expireOn": 2935054,
        "firstEligibleUd": null,
        "id": "0002920654-af135-000002",
        "index": 14584,
        "lastChangeOn": 2920654
      },
      {
        "accountId": null,
        "account": null,
        "name": "0002972030-eb0f1-000003",
        "status": "REMOVED",
        "createdInId": "0002972030-eb0f1-000003",
        "createdOn": 2972030,
        "expireOn": 2986430,
        "firstEligibleUd": null,
        "id": "0002972030-eb0f1-000003",
        "index": 14585,
        "lastChangeOn": 2972030
      },
      {
        "accountId": null,
        "account": null,
        "name": "0003013307-ab747-000002",
        "status": "REMOVED",
        "createdInId": "0003013307-ab747-000002",
        "createdOn": 3013307,
        "expireOn": 3027707,
        "firstEligibleUd": null,
        "id": "0003013307-ab747-000002",
        "index": 14586,
        "lastChangeOn": 3013307
      },
      {
        "accountId": null,
        "account": null,
        "name": "0003111160-d83a2-000002",
        "status": "REMOVED",
        "createdInId": "0003111160-d83a2-000002",
        "createdOn": 3111160,
        "expireOn": 3125560,
        "firstEligibleUd": null,
        "id": "0003111160-d83a2-000002",
        "index": 14587,
        "lastChangeOn": 3111160
      },
      {
        "accountId": null,
        "account": null,
        "name": "0003231555-d5852-000003",
        "status": "REMOVED",
        "createdInId": "0003231555-d5852-000003",
        "createdOn": 3231555,
        "expireOn": 3245955,
        "firstEligibleUd": null,
        "id": "0003231555-d5852-000003",
        "index": 14591,
        "lastChangeOn": 3231555
      },
      {
        "accountId": null,
        "account": null,
        "name": "0003295988-ce40c-000001",
        "status": "REMOVED",
        "createdInId": "0003295988-ce40c-000001",
        "createdOn": 3295988,
        "expireOn": 3310388,
        "firstEligibleUd": null,
        "id": "0003295988-ce40c-000001",
        "index": 14592,
        "lastChangeOn": 3295988
      },
      {
        "accountId": null,
        "account": null,
        "name": "0003221055-dc0af-000002",
        "status": "REMOVED",
        "createdInId": "0003221055-dc0af-000002",
        "createdOn": 3221055,
        "expireOn": 3235455,
        "firstEligibleUd": null,
        "id": "0003221055-dc0af-000002",
        "index": 14590,
        "lastChangeOn": 3221055
      },
      {
        "accountId": null,
        "account": null,
        "name": "0003311459-0dce8-000001",
        "status": "REMOVED",
        "createdInId": "0003311459-0dce8-000001",
        "createdOn": 3311459,
        "expireOn": 3325859,
        "firstEligibleUd": null,
        "id": "0003311459-0dce8-000001",
        "index": 14593,
        "lastChangeOn": 3311459
      },
      {
        "accountId": null,
        "account": null,
        "name": "0003344848-424ab-000001",
        "status": "REMOVED",
        "createdInId": "0003344848-424ab-000001",
        "createdOn": 3344848,
        "expireOn": 3359248,
        "firstEligibleUd": null,
        "id": "0003344848-424ab-000001",
        "index": 14595,
        "lastChangeOn": 3344848
      },
      {
        "accountId": null,
        "account": null,
        "name": "0003439195-e24f0-000001",
        "status": "REMOVED",
        "createdInId": "0003439195-e24f0-000001",
        "createdOn": 3439195,
        "expireOn": 3453595,
        "firstEligibleUd": null,
        "id": "0003439195-e24f0-000001",
        "index": 14596,
        "lastChangeOn": 3439195
      },
      {
        "accountId": null,
        "account": null,
        "name": "0003541070-69697-000001",
        "status": "REMOVED",
        "createdInId": "0003541070-69697-000001",
        "createdOn": 3541070,
        "expireOn": 3555470,
        "firstEligibleUd": null,
        "id": "0003541070-69697-000001",
        "index": 14597,
        "lastChangeOn": 3541070
      },
      {
        "accountId": null,
        "account": null,
        "name": "0003739364-c18fb-000001",
        "status": "REMOVED",
        "createdInId": "0003739364-c18fb-000001",
        "createdOn": 3739364,
        "expireOn": 3753764,
        "firstEligibleUd": null,
        "id": "0003739364-c18fb-000001",
        "index": 14598,
        "lastChangeOn": 3739364
      },
      {
        "accountId": null,
        "account": null,
        "name": "0004143628-38ef7-000001",
        "status": "REMOVED",
        "createdInId": "0004143628-38ef7-000001",
        "createdOn": 4143628,
        "expireOn": 4158028,
        "firstEligibleUd": null,
        "id": "0004143628-38ef7-000001",
        "index": 14600,
        "lastChangeOn": 4143628
      },
      {
        "accountId": null,
        "account": null,
        "name": "SpiranneGecko",
        "status": "REMOVED",
        "createdInId": "0003207864-4e4ce-000002",
        "createdOn": 3207864,
        "expireOn": 4090070,
        "firstEligibleUd": null,
        "id": "0003207864-4e4ce-000002",
        "index": 14589,
        "lastChangeOn": 3213470
      }
    ]
  }
}

```

Est-ce normal d’avoir des identités sans comptes associés dans l’indexer ?

---

<div class="post-metadata">

### Author: ![tuxmain](https://forum.duniter.org/user_avatar/forum.duniter.org/tuxmain/32/6423_2.png) [@tuxmain](https://forum.duniter.org/u/tuxmain)
#### Post date: [25 December 2024 09:10 UTC](https://forum.duniter.org/t/can-an-identity-have-no-associated-account/12824/2 "2024-12-25T09:10:54Z")

</div>

Le nom est encore dans IdentitiesNames mais l’identité n’est pas dans Identity ni dans IdentityIndexOf, donc l’identité n’existe plus. Le nom est conservé pour éviter son réemploi à des fins de phishing.

---

<div class="post-metadata">

### Author: ![poka](https://forum.duniter.org/user_avatar/forum.duniter.org/poka/32/6827_2.png) [@poka](https://forum.duniter.org/u/poka)
#### Post date: [25 December 2024 12:24 UTC](https://forum.duniter.org/t/can-an-identity-have-no-associated-account/12824/3 "2024-12-25T12:24:21Z")

</div>

Ok donc ça fait sens de garder les identities removed pour en garder une trace.

---

<div class="post-metadata">

### Author: ![HugoTrentesaux](https://forum.duniter.org/user_avatar/forum.duniter.org/hugotrentesaux/32/6396_2.png) [@HugoTrentesaux](https://forum.duniter.org/u/HugoTrentesaux)
#### Post date: [28 December 2024 12:25 UTC](https://forum.duniter.org/t/can-an-identity-have-no-associated-account/12824/4 "2024-12-28T12:25:44Z")

</div>

### Contexte

Une des difficultés de l’indexeur est de garder un index complet incluant des données supprimées sur Duniter à des fins d’historique. Un exemple avec ce bug : [Bug subsquid - #5 by HugoTrentesaux](https://forum.duniter.org/t/bug-subsquid/12354/5).

Tu noteras les champs account et accountRemoved dans le schéma [schema.graphql · main · nodes / duniter-squid · GitLab](https://git.duniter.org/nodes/duniter-squid/-/blob/main/schema.graphql?ref_type=heads#L200) :

```auto
"Identity"
type Identity @entity {
  "Identity index"
  index: Int! @index @unique
  "Current account"
  # should be null for a removed identity and only in this case
  account: Account @unique
  "Let track the account in case identity was removed"
  # should be non null for a removed identity and only in this case
  accountRemoved: Account
  "Name"
  name: String! @index

```

Le champ `account` porte la contrainte `@unique` mais Duniter ne force cette contrainte que pendant un certain temps. Quand l’identité est supprimée, une autre peut être créée en utilisant le même account. Que doit faire l’indexeur dans ce cas ?

C’est pour ça que dans `account`, `identity` est unique (`Identity`) alors que `removedIdentities` est multiple (`[Identity]`).

```auto
"Account table identified by its ss58 address"
type Account @entity {
  "current account for the identity"
  identity: Identity @derivedFrom(field: "account")
  "removed identities on this account"
  # they are handled apart to avoid dropping the @unique constraint of account
  removedIdentities: [Identity] @derivedFrom(field: "accountRemoved")

```

Il y aura le même problème quand on décidera de libérer des pseudos pour réutilisation. Pour l’instant, tous les outils partent du principe que [un pseudo = une identité]. Mais si Duniter libère le pseudo d’une identité supprimée il est possible qu’une autre identité l’utilise après. Dans ce cas l’indexeur devra faire la même chose : ajouter un champ `nameRemoved` pour garder une trace des anciennes identités qui ont utilisé ce pseudo.

### Réponse

> [@poka](#):
>
> Est-ce normal d’avoir des identités sans comptes associés dans l’indexer ?

Oui, et uniquement pour les identités qui ont été supprimées de Duniter :

> [@poka](#):
>
> ` "status": "REMOVED",`

Tu peux donc réutiliser la même clé pour créer une autre identité sans faire crasher l’indexeur et en conservant la contrainte `@unique` qu’il serait très gênant d’abandonner.

---

<div class="post-metadata">

### Author: ![cgeek](https://forum.duniter.org/user_avatar/forum.duniter.org/cgeek/32/279_2.png) [@cgeek](https://forum.duniter.org/u/cgeek)
#### Post date: [28 December 2024 16:02 UTC](https://forum.duniter.org/t/can-an-identity-have-no-associated-account/12824/5 "2024-12-28T16:02:49Z")

</div>

> [@HugoTrentesaux](#):
>
> Une des difficultés de l’indexeur est de garder un index complet incluant des données supprimées sur Duniter à des fins d’historique.

Tiens, cette remarque m’inspire une méthode de test : on devrait pouvoir créer des états (ex. : fiche de membre, [comme cette page de Duniter Panel](https://duniter--vue-coinduf-eu.ipns.pagu.re/#/idty/14601)) qui soient à la fois générés par de la consultation d’un indexeur _et_ par la consultation du Storage : le test consiste à vérifier qu’il n’existe aucune différence.

Cela permet autant de détecter des bugs côtés indexeur que côté Duniter.

Bien sûr la génération par consultation du Storage sera généralement beaucoup plus coûteuse (c’est bien pour ça qu’on crée des indexeurs), mais peu importe : il peut s’agir de tests sur demande. Des Golden Tests en quelque sorte.

J’ajoute ça à [Have a testing strategy (#141) · Issues · nodes / rust / Duniter v2S · GitLab](https://git.duniter.org/nodes/rust/duniter-v2s/-/issues/141).
