diff --git a/db/migrations/1705641339864-Data.js b/db/migrations/1705877992505-Data.js similarity index 86% rename from db/migrations/1705641339864-Data.js rename to db/migrations/1705877992505-Data.js index f998aee6aaae018df1b27002fe1e38910865b810..d6d2c1b7a83100742001d6bdace1af37be8e3b1d 100644 --- a/db/migrations/1705641339864-Data.js +++ b/db/migrations/1705877992505-Data.js @@ -1,5 +1,5 @@ -module.exports = class Data1705641339864 { - name = 'Data1705641339864' +module.exports = class Data1705877992505 { + name = 'Data1705877992505' async up(db) { await db.query(`CREATE TABLE "event" ("id" character varying NOT NULL, "index" integer NOT NULL, "phase" text NOT NULL, "pallet" text NOT NULL, "name" text NOT NULL, "args" jsonb, "args_str" text array, "block_id" character varying, "extrinsic_id" character varying, "call_id" character varying, CONSTRAINT "PK_30c2f3bbaf6d34a55f8ae6e4614" PRIMARY KEY ("id"))`) @@ -54,19 +54,21 @@ module.exports = class Data1705641339864 { await db.query(`CREATE INDEX "IDX_af577baa612d86d98a1ae58343" ON "change_owner_key" ("identity_id") `) await db.query(`CREATE INDEX "IDX_e09547f07faef3256f7f0381e9" ON "change_owner_key" ("previous_id") `) await db.query(`CREATE INDEX "IDX_9a9f8cdcae54d8b4375d70fe8b" ON "change_owner_key" ("next_id") `) - await db.query(`CREATE TABLE "identity" ("id" character varying NOT NULL, "index" integer NOT NULL, "name" text NOT NULL, "status" character varying(11) NOT NULL, "account_id" character varying, CONSTRAINT "REL_bafa9e6c71c3f69cef6602a809" UNIQUE ("account_id"), CONSTRAINT "PK_ff16a44186b286d5e626178f726" PRIMARY KEY ("id"))`) + await db.query(`CREATE TABLE "identity" ("id" character varying NOT NULL, "index" integer NOT NULL, "name" text NOT NULL, "status" character varying(11) NOT NULL, "smith_status" character varying(8), "account_id" character varying, CONSTRAINT "REL_bafa9e6c71c3f69cef6602a809" UNIQUE ("account_id"), CONSTRAINT "PK_ff16a44186b286d5e626178f726" PRIMARY KEY ("id"))`) await db.query(`CREATE UNIQUE INDEX "IDX_6f883c7979ea8dff46327f67cc" ON "identity" ("index") `) await db.query(`CREATE UNIQUE INDEX "IDX_bafa9e6c71c3f69cef6602a809" ON "identity" ("account_id") `) await db.query(`CREATE INDEX "IDX_883ba5be237fba47f2a2f39145" ON "identity" ("name") `) await db.query(`CREATE INDEX "IDX_ee232f862b258f533e70bbb24d" ON "identity" ("status") `) await db.query(`CREATE TABLE "account" ("id" character varying NOT NULL, "linked_identity_id" character varying, CONSTRAINT "PK_54115ee388cdb6d86bb4bf5b2ea" PRIMARY KEY ("id"))`) await db.query(`CREATE INDEX "IDX_73d14d249a6dcf9abe42eaa657" ON "account" ("linked_identity_id") `) - await db.query(`CREATE TABLE "membership" ("id" character varying NOT NULL, "expire_on" integer NOT NULL, "identity_id" character varying, CONSTRAINT "REL_efc905420f5f6bfded16c4eb97" UNIQUE ("identity_id"), CONSTRAINT "PK_83c1afebef3059472e7c37e8de8" PRIMARY KEY ("id"))`) + await db.query(`CREATE TABLE "membership_creation" ("id" character varying NOT NULL, "block_number" integer NOT NULL, "membership_id" character varying, CONSTRAINT "REL_e5d3930684fbf95b33e3c0b0a2" UNIQUE ("membership_id"), CONSTRAINT "PK_83b52baf73acff2c5fee412c759" PRIMARY KEY ("id"))`) + await db.query(`CREATE UNIQUE INDEX "IDX_e5d3930684fbf95b33e3c0b0a2" ON "membership_creation" ("membership_id") `) + await db.query(`CREATE TABLE "membership_renewal" ("id" character varying NOT NULL, "block_number" integer NOT NULL, "membership_id" character varying, CONSTRAINT "REL_5014c63f1d833f455417f80e82" UNIQUE ("membership_id"), CONSTRAINT "PK_dba26e0ad129ff43927cb431857" PRIMARY KEY ("id"))`) + await db.query(`CREATE UNIQUE INDEX "IDX_5014c63f1d833f455417f80e82" ON "membership_renewal" ("membership_id") `) + await db.query(`CREATE TABLE "membership_removal" ("id" character varying NOT NULL, "block_number" integer NOT NULL, "membership_id" character varying, CONSTRAINT "REL_8437e2d6c78482e62d19e92272" UNIQUE ("membership_id"), CONSTRAINT "PK_9b9bf7018f5d8e6061050805499" PRIMARY KEY ("id"))`) + await db.query(`CREATE UNIQUE INDEX "IDX_8437e2d6c78482e62d19e92272" ON "membership_removal" ("membership_id") `) + await db.query(`CREATE TABLE "membership" ("id" character varying NOT NULL, "active" boolean NOT NULL, "created_on" integer NOT NULL, "expire_on" integer NOT NULL, "identity_id" character varying, CONSTRAINT "REL_efc905420f5f6bfded16c4eb97" UNIQUE ("identity_id"), CONSTRAINT "PK_83c1afebef3059472e7c37e8de8" PRIMARY KEY ("id"))`) await db.query(`CREATE UNIQUE INDEX "IDX_efc905420f5f6bfded16c4eb97" ON "membership" ("identity_id") `) - await db.query(`CREATE INDEX "IDX_a3f3d8dc21447800f72c0a27b2" ON "membership" ("expire_on") `) - await db.query(`CREATE TABLE "smith_membership" ("id" character varying NOT NULL, "status" character varying(8) NOT NULL, "identity_id" character varying, CONSTRAINT "REL_8645aa09a4cfa921be42f1bdc1" UNIQUE ("identity_id"), CONSTRAINT "PK_ec71fc36eab1a7cb666eb11f60a" PRIMARY KEY ("id"))`) - await db.query(`CREATE UNIQUE INDEX "IDX_8645aa09a4cfa921be42f1bdc1" ON "smith_membership" ("identity_id") `) - await db.query(`CREATE INDEX "IDX_553a87a08bf4e7909831e6b03b" ON "smith_membership" ("status") `) await db.query(`ALTER TABLE "event" ADD CONSTRAINT "FK_2b0d35d675c4f99751855c45021" FOREIGN KEY ("block_id") REFERENCES "block"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`) await db.query(`ALTER TABLE "event" ADD CONSTRAINT "FK_129efedcb305c80256db2d57a59" FOREIGN KEY ("extrinsic_id") REFERENCES "extrinsic"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`) await db.query(`ALTER TABLE "event" ADD CONSTRAINT "FK_83cf1bd59aa4521ed882fa51452" FOREIGN KEY ("call_id") REFERENCES "call"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`) @@ -89,8 +91,10 @@ module.exports = class Data1705641339864 { await db.query(`ALTER TABLE "change_owner_key" ADD CONSTRAINT "FK_9a9f8cdcae54d8b4375d70fe8be" FOREIGN KEY ("next_id") REFERENCES "account"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`) await db.query(`ALTER TABLE "identity" ADD CONSTRAINT "FK_bafa9e6c71c3f69cef6602a8095" FOREIGN KEY ("account_id") REFERENCES "account"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`) await db.query(`ALTER TABLE "account" ADD CONSTRAINT "FK_73d14d249a6dcf9abe42eaa6573" FOREIGN KEY ("linked_identity_id") REFERENCES "identity"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`) + await db.query(`ALTER TABLE "membership_creation" ADD CONSTRAINT "FK_e5d3930684fbf95b33e3c0b0a27" FOREIGN KEY ("membership_id") REFERENCES "membership"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`) + await db.query(`ALTER TABLE "membership_renewal" ADD CONSTRAINT "FK_5014c63f1d833f455417f80e825" FOREIGN KEY ("membership_id") REFERENCES "membership"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`) + await db.query(`ALTER TABLE "membership_removal" ADD CONSTRAINT "FK_8437e2d6c78482e62d19e922720" FOREIGN KEY ("membership_id") REFERENCES "membership"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`) await db.query(`ALTER TABLE "membership" ADD CONSTRAINT "FK_efc905420f5f6bfded16c4eb978" FOREIGN KEY ("identity_id") REFERENCES "identity"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`) - await db.query(`ALTER TABLE "smith_membership" ADD CONSTRAINT "FK_8645aa09a4cfa921be42f1bdc1b" FOREIGN KEY ("identity_id") REFERENCES "identity"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`) } async down(db) { @@ -153,12 +157,14 @@ module.exports = class Data1705641339864 { await db.query(`DROP INDEX "public"."IDX_ee232f862b258f533e70bbb24d"`) await db.query(`DROP TABLE "account"`) await db.query(`DROP INDEX "public"."IDX_73d14d249a6dcf9abe42eaa657"`) + await db.query(`DROP TABLE "membership_creation"`) + await db.query(`DROP INDEX "public"."IDX_e5d3930684fbf95b33e3c0b0a2"`) + await db.query(`DROP TABLE "membership_renewal"`) + await db.query(`DROP INDEX "public"."IDX_5014c63f1d833f455417f80e82"`) + await db.query(`DROP TABLE "membership_removal"`) + await db.query(`DROP INDEX "public"."IDX_8437e2d6c78482e62d19e92272"`) await db.query(`DROP TABLE "membership"`) await db.query(`DROP INDEX "public"."IDX_efc905420f5f6bfded16c4eb97"`) - await db.query(`DROP INDEX "public"."IDX_a3f3d8dc21447800f72c0a27b2"`) - await db.query(`DROP TABLE "smith_membership"`) - await db.query(`DROP INDEX "public"."IDX_8645aa09a4cfa921be42f1bdc1"`) - await db.query(`DROP INDEX "public"."IDX_553a87a08bf4e7909831e6b03b"`) await db.query(`ALTER TABLE "event" DROP CONSTRAINT "FK_2b0d35d675c4f99751855c45021"`) await db.query(`ALTER TABLE "event" DROP CONSTRAINT "FK_129efedcb305c80256db2d57a59"`) await db.query(`ALTER TABLE "event" DROP CONSTRAINT "FK_83cf1bd59aa4521ed882fa51452"`) @@ -181,7 +187,9 @@ module.exports = class Data1705641339864 { await db.query(`ALTER TABLE "change_owner_key" DROP CONSTRAINT "FK_9a9f8cdcae54d8b4375d70fe8be"`) await db.query(`ALTER TABLE "identity" DROP CONSTRAINT "FK_bafa9e6c71c3f69cef6602a8095"`) await db.query(`ALTER TABLE "account" DROP CONSTRAINT "FK_73d14d249a6dcf9abe42eaa6573"`) + await db.query(`ALTER TABLE "membership_creation" DROP CONSTRAINT "FK_e5d3930684fbf95b33e3c0b0a27"`) + await db.query(`ALTER TABLE "membership_renewal" DROP CONSTRAINT "FK_5014c63f1d833f455417f80e825"`) + await db.query(`ALTER TABLE "membership_removal" DROP CONSTRAINT "FK_8437e2d6c78482e62d19e922720"`) await db.query(`ALTER TABLE "membership" DROP CONSTRAINT "FK_efc905420f5f6bfded16c4eb978"`) - await db.query(`ALTER TABLE "smith_membership" DROP CONSTRAINT "FK_8645aa09a4cfa921be42f1bdc1b"`) } } diff --git a/schema.graphql b/schema.graphql index 0cbef69ae81da4ff66299a317b3c0c8aced06c05..590825b9b0bd17a48c118087638fd9473ab87f00 100644 --- a/schema.graphql +++ b/schema.graphql @@ -147,8 +147,14 @@ type Identity @entity { account: Account! @unique "Name" name: String! @index - "Status" + "Status of the identity" + # mixes identity pallet status (Unconfirmed, Unvalidated, Revoked) + # and membership pallet status (Member, WasMember) status: IdentityStatus! @index + "Smith status of the identity" + # no need for smith membership history for this one + # nullable field defaulting to null because most identity are not smith + smithStatus: SmithStatus "Certifications issued" certIssued: [Cert!] @derivedFrom(field: "issuer") "Certifications received" @@ -158,9 +164,8 @@ type Identity @entity { "Smith certifications received" smithCertReceived: [SmithCert!] @derivedFrom(field: "receiver") "Membership of the identity" + # this is here that you get all info about the membership history of the identiy membership: Membership @derivedFrom(field: "identity") - "Smith Membership of the identity" - smithMembership: SmithMembership @derivedFrom(field: "identity") "Owner key changes" ownerKeyChange: [ChangeOwnerKey!] @derivedFrom(field: "identity") "linked accounts" @@ -215,13 +220,36 @@ type SmithCert @entity { "Membership" type Membership @entity { identity: Identity! @unique @index - expireOn: Int! @index + "whether the membership is active" + # useful for indexation + active: Boolean! + "the last createdOn value" + # even if active is false + # updated when membership is created or renewed + createdOn: Int! + "the current expireOn value" + # can be in the future if membership is active + # or in the past if membership is removed + expireOn: Int! + # history of the membership + creation: [MembershipCreation!] @derivedFrom(field: "membership") + renewal: [MembershipRenewal!] @derivedFrom(field: "membership") + removal: [MembershipRemoval!] @derivedFrom(field: "membership") } - -"Smith membership" -type SmithMembership @entity { - identity: Identity! @unique @index - status: SmithStatus! @index +"Membership creation" +type MembershipCreation @entity { + membership: Membership! @unique @index + blockNumber: Int! +} +"Membership renewal" +type MembershipRenewal @entity { + membership: Membership! @unique @index + blockNumber: Int! +} +"Membership removal" +type MembershipRemoval @entity { + membership: Membership! @unique @index + blockNumber: Int! } enum IdentityStatus { diff --git a/src/data_handler.ts b/src/data_handler.ts index f0eb981b60a6b1539eee8d831a54af9b3fe40215..1d4d4ac6470cbc2a3aa04669933ec5b52ff4fab0 100644 --- a/src/data_handler.ts +++ b/src/data_handler.ts @@ -9,9 +9,11 @@ import { Identity, Transfer, IdentityStatus, - SmithMembership, SmithStatus, Membership, + MembershipRemoval, + MembershipCreation, + MembershipRenewal, } from "./model"; import { In } from "typeorm"; import { Address, Ctx, Data, IdtyIndex, NewData } from "./types_custom"; @@ -25,6 +27,9 @@ export class DataHandler { accounts: new Map(), identities: new Map(), memberships: new Map(), + membershipCreation: [], + membershipRenewal: [], + membershipRemoval: [], changeOwnerKey: [], transfers: [], certification: new Map(), @@ -32,7 +37,6 @@ export class DataHandler { certRenewal: [], certRemoval: [], smithCert: new Map(), - smithMemberships: new Map(), }; } @@ -151,38 +155,49 @@ export class DataHandler { // Process membership added for (const membershipAdded of newData.membershipAdded) { - const identity = await this.getIdtyByIndexOrFail(ctx, membershipAdded.index); - const id = identity.id; + const { id, index, expire_on, blockNumber } = membershipAdded; + const identity = await this.getIdtyByIndexOrFail(ctx, index); // membership should not exist before creation - const membership = new Membership({ id, identity, expireOn: membershipAdded.expire_on }); + const membership = new Membership({ id, identity, expireOn: expire_on, active: true }); identity.status = IdentityStatus.Member - this.data.memberships.set(membershipAdded.index, membership); + this.data.membershipCreation.push(new MembershipCreation({ id: id, membership, blockNumber: blockNumber })); + this.data.memberships.set(index, membership); this.data.identities.set(identity.index, identity); - } // Process membership renewed for (const membershipRenewed of newData.membershipRenewed) { - const identity = await this.getIdtyByIndexOrFail(ctx, membershipRenewed.index); - const id = identity.id; - // membership should exist for renew - const membership = await ctx.store.findOneByOrFail(Membership, { id }) - + const { id, index, expire_on, blockNumber } = membershipRenewed; + const identity = await this.getIdtyByIndexOrFail(ctx, index); + const membership = await ctx.store.findOneOrFail(Membership, { + relations: { identity: true }, + where: { identity: { index: index } }, + }); // Set new expiration time - membership.expireOn = membershipRenewed.expire_on; + membership.expireOn = expire_on; + membership.active = true; + identity.status = IdentityStatus.Member - this.data.memberships.set(membershipRenewed.index, membership); + this.data.membershipRenewal.push(new MembershipRenewal({ id: id, membership, blockNumber: blockNumber })); + this.data.memberships.set(index, membership); + this.data.identities.set(identity.index, identity); } // Process membership removed for (const membershipRemoved of newData.membershipRemoved) { - const identity = await this.getIdtyByIndexOrFail(ctx, membershipRemoved.index); - const id = identity.id; + const { id, index, blockNumber } = membershipRemoved; + const identity = await this.getIdtyByIndexOrFail(ctx, index); + const membership = await ctx.store.findOneOrFail(Membership, { + relations: { identity: true }, + where: { identity: { index: index } }, + }); + identity.status = IdentityStatus.NotMember; + membership.active = false; - // membership should exist for remove - await ctx.store.remove(Membership, id); + this.data.membershipRemoval.push(new MembershipRemoval({ id: id, membership, blockNumber: blockNumber })); + this.data.memberships.set(index, membership); this.data.identities.set(identity.index, identity); } @@ -295,10 +310,9 @@ export class DataHandler { for (const invitedSmith of newData.smithInvited) { const { idtyIndex } = invitedSmith; const identity = await this.getIdtyByIndexOrFail(ctx, idtyIndex); - const id = identity.id; - // smith should not exist before invitation - const smith = new SmithMembership({ id, identity, status: SmithStatus.Invited }); - this.data.smithMemberships.set(idtyIndex, smith); + identity.smithStatus = SmithStatus.Invited; + + this.data.identities.set(idtyIndex, identity); } // Process Smith invitation accepted @@ -306,15 +320,8 @@ export class DataHandler { const { idtyIndex } = acceptedSmithInvitations; const identity = await this.getIdtyByIndexOrFail(ctx, idtyIndex); - const id = identity.id; - // should never fail because smith has been invited before - const smith = await ctx.store.findOneByOrFail(SmithMembership, { id }) - // const smith = await ctx.store.findOneOrFail(SmithMembership, { - // relations: { identity: true }, - // where: { identity: { index: idtyIndex } }, - // }); - smith.status = SmithStatus.Pending; - this.data.smithMemberships.set(idtyIndex, smith); + identity.smithStatus = SmithStatus.Pending; + this.data.identities.set(idtyIndex, identity); } // Process Smith promotion @@ -322,15 +329,8 @@ export class DataHandler { const { idtyIndex } = promotedSmith; const identity = await this.getIdtyByIndexOrFail(ctx, idtyIndex); - const id = identity.id; - // should never fail because smith has been invited before - const smith = await ctx.store.findOneByOrFail(SmithMembership, { id }) - // const smith = await ctx.store.findOneOrFail(SmithMembership, { - // relations: { identity: true }, - // where: { identity: { index: idtyIndex } }, - // }); - smith.status = SmithStatus.Smith; - this.data.smithMemberships.set(idtyIndex, smith); + identity.smithStatus = SmithStatus.Smith; + this.data.identities.set(idtyIndex, identity); } // Process Smith exlusion @@ -338,12 +338,9 @@ export class DataHandler { const { idtyIndex } = excludedSmith; const identity = await this.getIdtyByIndexOrFail(ctx, idtyIndex); - const id = identity.id; - // should never fail because smith has been invited before - const smith = await ctx.store.findOneByOrFail(SmithMembership, { id }) - smith.status = SmithStatus.Excluded; - this.data.smithMemberships.set(idtyIndex, smith); + identity.smithStatus = SmithStatus.Excluded; + this.data.identities.set(idtyIndex, identity); } // Process account links @@ -437,8 +434,6 @@ export class DataHandler { await ctx.store.upsert([...this.data.identities.values()]); // memberships can have been changed (renewed, removed...) or added (added) await ctx.store.upsert([...this.data.memberships.values()]); - // smiths can have been changed (invited, pending...) or added (invited) - await ctx.store.upsert([...this.data.smithMemberships.values()]); // certs can have been changed (renewed, removed...) await ctx.store.upsert([...this.data.certification.values()]); await ctx.store.upsert([...this.data.smithCert.values()]); @@ -449,6 +444,9 @@ export class DataHandler { await ctx.store.insert(this.data.certCreation); await ctx.store.insert(this.data.certRenewal); await ctx.store.insert(this.data.certRemoval); + await ctx.store.insert(this.data.membershipCreation); + await ctx.store.insert(this.data.membershipRenewal); + await ctx.store.insert(this.data.membershipRemoval); // Apply changes in database await ctx.store.commit(); diff --git a/src/genesis.ts b/src/genesis.ts index 5223d139b230544449ba1817c7af75808109758e..ab584dba23602fb76e4f09e8d8eacf520f6c359a 100644 --- a/src/genesis.ts +++ b/src/genesis.ts @@ -1,6 +1,6 @@ import type { Address, IdtyIndex, Ctx, Genesis, TransactionHistory, Tx } from "./types_custom"; import { readFileSync } from "fs"; -import { Account, Cert, SmithCert, Identity, Membership, SmithMembership, Transfer, ChangeOwnerKey, IdentityStatus, SmithStatus } from "./model"; +import { Account, Cert, SmithCert, Identity, Membership, Transfer, ChangeOwnerKey, SmithStatus, MembershipCreation } from "./model"; import path from "path/posix"; export async function saveGenesis(ctx: Ctx) { @@ -18,7 +18,7 @@ export async function saveGenesis(ctx: Ctx) { const certs: Cert[] = []; const smithCerts: SmithCert[] = []; const memberships: Membership[] = []; - const smithMemberships: SmithMembership[] = []; + const membershipsCreation: MembershipCreation[] = []; // collect accounts for (const [address] of Object.entries(genesis.account.accounts)) { @@ -82,13 +82,10 @@ export async function saveGenesis(ctx: Ctx) { // collect smith memberships for (const [idtyIdex, smithCertsData] of Object.entries(genesis.smithMembers.initialSmiths)) { const [isOnline, certs] = smithCertsData as [boolean, number[]]; - smithMemberships.push( - new SmithMembership({ - id: `genesis-${idtyIdex}`, - identity: identities.get(parseInt(idtyIdex)), - status: SmithStatus.Smith, - }) - ); + const identity = identities.get(parseInt(idtyIdex))!; + identity.smithStatus = SmithStatus.Smith; + identities.set(identity.index, identity); + for (const issuer_index of certs) { smithCerts.push( new SmithCert({ @@ -103,13 +100,16 @@ export async function saveGenesis(ctx: Ctx) { // collect memberships for (const [idtyId, mshipInfo] of Object.entries(genesis.membership.memberships)) { - memberships.push( - new Membership({ - id: `genesis-${idtyId}`, - identity: identities.get(parseInt(idtyId)), - expireOn: mshipInfo.expire_on, - }) - ); + const membership = new Membership({ + id: `genesis-${idtyId}`, + identity: identities.get(parseInt(idtyId)), + createdOn: 0, + expireOn: mshipInfo.expire_on, + active: true, + }); + + memberships.push(membership); + membershipsCreation.push(new MembershipCreation({ id: `genesis-${idtyId}`, membership: membership, blockNumber: 0 })); } ctx.log.info("Saving genesis"); @@ -121,7 +121,7 @@ export async function saveGenesis(ctx: Ctx) { await ctx.store.insert(chok); await ctx.store.insert(smithCerts); await ctx.store.insert(memberships); - await ctx.store.insert(smithMemberships); + await ctx.store.insert(membershipsCreation); // await ctx.store.flush(); // do not flush otherwise we lose cache ctx.log.info("Genesis saved"); diff --git a/src/main.ts b/src/main.ts index d6940e0d66988f87d6c1f34b43e1a905299bf608..7228002720f5a55e96efb4d8dc865470615a06b8 100644 --- a/src/main.ts +++ b/src/main.ts @@ -205,6 +205,7 @@ function collectDataFromEvents(ctx: Ctx, newData: NewData) { id: event.id, index: membershipAdded.member, expire_on: membershipAdded.expireOn, + blockNumber: block.header.height, }); break; } @@ -215,6 +216,7 @@ function collectDataFromEvents(ctx: Ctx, newData: NewData) { id: event.id, index: membershipRemoved.member, reason: membershipRemoved.reason, + blockNumber: block.header.height, }); break; } @@ -225,6 +227,7 @@ function collectDataFromEvents(ctx: Ctx, newData: NewData) { id: event.id, index: membershipRenewed.member, expire_on: membershipRenewed.expireOn, + blockNumber: block.header.height, }); break; } diff --git a/src/model/generated/identity.model.ts b/src/model/generated/identity.model.ts index 779a6e90f727d52e713ba25432282d3af883a1e1..8360566b22ff0eba3d30ee106e28040ae99d51eb 100644 --- a/src/model/generated/identity.model.ts +++ b/src/model/generated/identity.model.ts @@ -1,10 +1,10 @@ import {Entity as Entity_, Column as Column_, PrimaryColumn as PrimaryColumn_, Index as Index_, OneToOne as OneToOne_, JoinColumn as JoinColumn_, OneToMany as OneToMany_} from "typeorm" import {Account} from "./account.model" import {IdentityStatus} from "./_identityStatus" +import {SmithStatus} from "./_smithStatus" import {Cert} from "./cert.model" import {SmithCert} from "./smithCert.model" import {Membership} from "./membership.model" -import {SmithMembership} from "./smithMembership.model" import {ChangeOwnerKey} from "./changeOwnerKey.model" /** @@ -42,12 +42,18 @@ export class Identity { name!: string /** - * Status + * Status of the identity */ @Index_() @Column_("varchar", {length: 11, nullable: false}) status!: IdentityStatus + /** + * Smith status of the identity + */ + @Column_("varchar", {length: 8, nullable: true}) + smithStatus!: SmithStatus | undefined | null + /** * Certifications issued */ @@ -76,10 +82,6 @@ export class Identity { * Membership of the identity */ - /** - * Smith Membership of the identity - */ - /** * Owner key changes */ diff --git a/src/model/generated/index.ts b/src/model/generated/index.ts index a4c06db7570869a7f7b9a7fc49ece023d0e44f33..aceafa281d671b8907aafebec94ea44a2df6756a 100644 --- a/src/model/generated/index.ts +++ b/src/model/generated/index.ts @@ -10,6 +10,7 @@ export * from "./account.model" export * from "./transfer.model" export * from "./identity.model" export * from "./_identityStatus" +export * from "./_smithStatus" export * from "./changeOwnerKey.model" export * from "./cert.model" export * from "./certCreation.model" @@ -17,5 +18,6 @@ export * from "./certRenewal.model" export * from "./certRemoval.model" export * from "./smithCert.model" export * from "./membership.model" -export * from "./smithMembership.model" -export * from "./_smithStatus" +export * from "./membershipCreation.model" +export * from "./membershipRenewal.model" +export * from "./membershipRemoval.model" diff --git a/src/model/generated/membership.model.ts b/src/model/generated/membership.model.ts index 9bec4caaa0173de55369181c0a1d53d8fc089453..d4a473e720ea66b9733f1dcad4b93aa510345801 100644 --- a/src/model/generated/membership.model.ts +++ b/src/model/generated/membership.model.ts @@ -1,5 +1,8 @@ -import {Entity as Entity_, Column as Column_, PrimaryColumn as PrimaryColumn_, OneToOne as OneToOne_, Index as Index_, JoinColumn as JoinColumn_} from "typeorm" +import {Entity as Entity_, Column as Column_, PrimaryColumn as PrimaryColumn_, OneToOne as OneToOne_, Index as Index_, JoinColumn as JoinColumn_, OneToMany as OneToMany_} from "typeorm" import {Identity} from "./identity.model" +import {MembershipCreation} from "./membershipCreation.model" +import {MembershipRenewal} from "./membershipRenewal.model" +import {MembershipRemoval} from "./membershipRemoval.model" /** * Membership @@ -18,7 +21,30 @@ export class Membership { @JoinColumn_() identity!: Identity - @Index_() + /** + * whether the membership is active + */ + @Column_("bool", {nullable: false}) + active!: boolean + + /** + * the last createdOn value + */ + @Column_("int4", {nullable: false}) + createdOn!: number + + /** + * the current expireOn value + */ @Column_("int4", {nullable: false}) expireOn!: number + + @OneToMany_(() => MembershipCreation, e => e.membership) + creation!: MembershipCreation[] + + @OneToMany_(() => MembershipRenewal, e => e.membership) + renewal!: MembershipRenewal[] + + @OneToMany_(() => MembershipRemoval, e => e.membership) + removal!: MembershipRemoval[] } diff --git a/src/model/generated/membershipCreation.model.ts b/src/model/generated/membershipCreation.model.ts new file mode 100644 index 0000000000000000000000000000000000000000..813ab355d03c173456ac87995c81be16cd9ced20 --- /dev/null +++ b/src/model/generated/membershipCreation.model.ts @@ -0,0 +1,23 @@ +import {Entity as Entity_, Column as Column_, PrimaryColumn as PrimaryColumn_, OneToOne as OneToOne_, Index as Index_, JoinColumn as JoinColumn_} from "typeorm" +import {Membership} from "./membership.model" + +/** + * Membership creation + */ +@Entity_() +export class MembershipCreation { + constructor(props?: Partial<MembershipCreation>) { + Object.assign(this, props) + } + + @PrimaryColumn_() + id!: string + + @Index_({unique: true}) + @OneToOne_(() => Membership, {nullable: true}) + @JoinColumn_() + membership!: Membership + + @Column_("int4", {nullable: false}) + blockNumber!: number +} diff --git a/src/model/generated/membershipRemoval.model.ts b/src/model/generated/membershipRemoval.model.ts new file mode 100644 index 0000000000000000000000000000000000000000..baed4d9f553e025ca54688d70c4a2528a69169a8 --- /dev/null +++ b/src/model/generated/membershipRemoval.model.ts @@ -0,0 +1,23 @@ +import { Entity as Entity_, Column as Column_, PrimaryColumn as PrimaryColumn_, OneToOne as OneToOne_, Index as Index_, JoinColumn as JoinColumn_ } from "typeorm" +import { Membership } from "./membership.model" + +/** + * Membership removal + */ +@Entity_() +export class MembershipRemoval { + constructor(props?: Partial<MembershipRemoval>) { + Object.assign(this, props) + } + + @PrimaryColumn_() + id!: string + + @Index_({ unique: true }) + @OneToOne_(() => Membership, { nullable: true }) + @JoinColumn_() + membership!: Membership + + @Column_("int4", { nullable: false }) + blockNumber!: number +} diff --git a/src/model/generated/membershipRenewal.model.ts b/src/model/generated/membershipRenewal.model.ts new file mode 100644 index 0000000000000000000000000000000000000000..6b633e6c6fe930f80db49a76412d19ac1acbcda6 --- /dev/null +++ b/src/model/generated/membershipRenewal.model.ts @@ -0,0 +1,23 @@ +import {Entity as Entity_, Column as Column_, PrimaryColumn as PrimaryColumn_, OneToOne as OneToOne_, Index as Index_, JoinColumn as JoinColumn_} from "typeorm" +import {Membership} from "./membership.model" + +/** + * Membership renewal + */ +@Entity_() +export class MembershipRenewal { + constructor(props?: Partial<MembershipRenewal>) { + Object.assign(this, props) + } + + @PrimaryColumn_() + id!: string + + @Index_({unique: true}) + @OneToOne_(() => Membership, {nullable: true}) + @JoinColumn_() + membership!: Membership + + @Column_("int4", {nullable: false}) + blockNumber!: number +} diff --git a/src/model/generated/smithMembership.model.ts b/src/model/generated/smithMembership.model.ts deleted file mode 100644 index 44dd305beeeb9628abef0f9a0cf25fb09493555c..0000000000000000000000000000000000000000 --- a/src/model/generated/smithMembership.model.ts +++ /dev/null @@ -1,25 +0,0 @@ -import {Entity as Entity_, Column as Column_, PrimaryColumn as PrimaryColumn_, OneToOne as OneToOne_, Index as Index_, JoinColumn as JoinColumn_} from "typeorm" -import {Identity} from "./identity.model" -import {SmithStatus} from "./_smithStatus" - -/** - * Smith membership - */ -@Entity_() -export class SmithMembership { - constructor(props?: Partial<SmithMembership>) { - Object.assign(this, props) - } - - @PrimaryColumn_() - id!: string - - @Index_({unique: true}) - @OneToOne_(() => Identity, {nullable: true}) - @JoinColumn_() - identity!: Identity - - @Index_() - @Column_("varchar", {length: 8, nullable: false}) - status!: SmithStatus -} diff --git a/src/types_custom.ts b/src/types_custom.ts index dcab2c2a5e1c16457423f02572f0896e9223f5da..aa1ee9f6c81887e6ec868ac339db5f6eab69c353 100644 --- a/src/types_custom.ts +++ b/src/types_custom.ts @@ -8,8 +8,10 @@ import { Identity, IdentityStatus, Membership, + MembershipCreation, + MembershipRemoval, + MembershipRenewal, SmithCert, - SmithMembership, Transfer, } from "./model"; import { ProcessorContext } from "./processor"; @@ -79,7 +81,7 @@ interface GenIdtyData { } interface GenMemberships { - memberships: Map<number, GenMembership>; + memberships: Map<IdtyIndex, GenMembership>; } interface GenMembership { @@ -117,6 +119,9 @@ export interface Data { accounts: Map<Address, Account>; identities: Map<IdtyIndex, Identity>; memberships: Map<IdtyIndex, Membership>; + membershipCreation: MembershipCreation[]; + membershipRenewal: MembershipRenewal[]; + membershipRemoval: MembershipRemoval[]; changeOwnerKey: ChangeOwnerKey[]; transfers: Transfer[]; certification: Map<[IdtyIndex, IdtyIndex], Cert>; @@ -124,7 +129,6 @@ export interface Data { certRenewal: CertRenewal[]; certRemoval: CertRemoval[]; smithCert: Map<[IdtyIndex, IdtyIndex], SmithCert>; - smithMemberships: Map<IdtyIndex, SmithMembership>; } // =========================== Events =========================== // @@ -262,18 +266,21 @@ interface MembershipAddedEvent { id: string; index: IdtyIndex; expire_on: number; + blockNumber: BlockNumber; } interface MembershipRemovedEvent { id: string; index: IdtyIndex; reason: MembershipRemovalReason; + blockNumber: BlockNumber; } interface MembershipRenewedEvent { id: string; index: IdtyIndex; expire_on: number; + blockNumber: BlockNumber; } interface AccountLinkEvent {