diff --git a/commands.json b/commands.json index 19fa34a8e7a3fa61bb9b6a79f35957c92f7270a8..21f730f615bead72796c14d9c667950f8effa000 100644 --- a/commands.json +++ b/commands.json @@ -12,7 +12,12 @@ }, "up": { "description": "Start a PG database and Hasura GraphQL engine", - "cmd": ["./scripts/start_dev_docker.sh"] + "deps": ["up-only", "migration:apply", "hasura:apply"], + "cmd": ["echo", "Database and Hasura have been started"] + }, + "up-only": { + "description": "Start a PG database and Hasura GraphQL engine", + "cmd": ["docker", "compose", "-f", "docker-compose.dev.yml", "up", "-d"] }, "down": { "description": "Drop a PG database and Hasura GraphQL engine", @@ -45,6 +50,8 @@ "db:update": { "description": "Apply database changes: codegen, generate and apply migrations, clean migrations, track tables and functions", "deps": [ + "down", + "up-only", "codegen", "migration:generate", "migration:apply", diff --git a/db/migrations/1708969307321-Data.js b/db/migrations/1713861445705-Data.js similarity index 97% rename from db/migrations/1708969307321-Data.js rename to db/migrations/1713861445705-Data.js index 75242c59b623dc45202a74444922215ea27301a0..d229bdd484c24d4880b817ee9348ce55b05fdb03 100644 --- a/db/migrations/1708969307321-Data.js +++ b/db/migrations/1713861445705-Data.js @@ -1,5 +1,5 @@ -module.exports = class Data1708969307321 { - name = 'Data1708969307321' +module.exports = class Data1713861445705 { + name = 'Data1713861445705' 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"))`) @@ -42,9 +42,10 @@ module.exports = class Data1708969307321 { await db.query(`CREATE INDEX "IDX_d2bc74ffa9c2571da03670f2c8" ON "cert_event" ("cert_id") `) await db.query(`CREATE INDEX "IDX_411c2bb1469a8a96762ceb00ae" ON "cert_event" ("event_id") `) await db.query(`CREATE INDEX "IDX_53154146094ec7b030dbc31388" ON "cert_event" ("block_number") `) - await db.query(`CREATE TABLE "cert" ("id" character varying NOT NULL, "is_active" boolean NOT NULL, "created_on" integer NOT NULL, "expire_on" integer NOT NULL, "issuer_id" character varying, "receiver_id" character varying, CONSTRAINT "PK_6a0ce80cc860598b4f16c00998c" PRIMARY KEY ("id"))`) + await db.query(`CREATE TABLE "cert" ("id" character varying NOT NULL, "is_active" boolean NOT NULL, "created_on" integer NOT NULL, "expire_on" integer NOT NULL, "issuer_id" character varying, "receiver_id" character varying, "created_in_id" character varying, CONSTRAINT "PK_6a0ce80cc860598b4f16c00998c" PRIMARY KEY ("id"))`) await db.query(`CREATE INDEX "IDX_70592e488b2e75cd8a2fa79826" ON "cert" ("issuer_id") `) await db.query(`CREATE INDEX "IDX_262e29ab91c8ebc727cc518f2f" ON "cert" ("receiver_id") `) + await db.query(`CREATE INDEX "IDX_ad35ca166ad24ecea43d7ebfca" ON "cert" ("created_in_id") `) await db.query(`CREATE TABLE "smith_cert" ("id" character varying NOT NULL, "created_on" integer NOT NULL, "issuer_id" character varying, "receiver_id" character varying, CONSTRAINT "PK_ae2ef36c9f6d40348c86230fd35" PRIMARY KEY ("id"))`) await db.query(`CREATE INDEX "IDX_ae67cbd087fcea0e1ec2f70cd0" ON "smith_cert" ("issuer_id") `) await db.query(`CREATE INDEX "IDX_5e414c1d12af16165881a16b63" ON "smith_cert" ("receiver_id") `) @@ -84,6 +85,7 @@ module.exports = class Data1708969307321 { await db.query(`ALTER TABLE "cert_event" ADD CONSTRAINT "FK_411c2bb1469a8a96762ceb00ae6" FOREIGN KEY ("event_id") REFERENCES "event"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`) await db.query(`ALTER TABLE "cert" ADD CONSTRAINT "FK_70592e488b2e75cd8a2fa798261" FOREIGN KEY ("issuer_id") REFERENCES "identity"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`) await db.query(`ALTER TABLE "cert" ADD CONSTRAINT "FK_262e29ab91c8ebc727cc518f2fb" FOREIGN KEY ("receiver_id") REFERENCES "identity"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`) + await db.query(`ALTER TABLE "cert" ADD CONSTRAINT "FK_ad35ca166ad24ecea43d7ebfca9" FOREIGN KEY ("created_in_id") REFERENCES "event"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`) await db.query(`ALTER TABLE "smith_cert" ADD CONSTRAINT "FK_ae67cbd087fcea0e1ec2f70cd04" FOREIGN KEY ("issuer_id") REFERENCES "identity"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`) await db.query(`ALTER TABLE "smith_cert" ADD CONSTRAINT "FK_5e414c1d12af16165881a16b638" FOREIGN KEY ("receiver_id") REFERENCES "identity"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`) await db.query(`ALTER TABLE "membership_event" ADD CONSTRAINT "FK_fbbd75d84ab6cc2aafeaf37a03f" FOREIGN KEY ("identity_id") REFERENCES "identity"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`) @@ -143,6 +145,7 @@ module.exports = class Data1708969307321 { await db.query(`DROP TABLE "cert"`) await db.query(`DROP INDEX "public"."IDX_70592e488b2e75cd8a2fa79826"`) await db.query(`DROP INDEX "public"."IDX_262e29ab91c8ebc727cc518f2f"`) + await db.query(`DROP INDEX "public"."IDX_ad35ca166ad24ecea43d7ebfca"`) await db.query(`DROP TABLE "smith_cert"`) await db.query(`DROP INDEX "public"."IDX_ae67cbd087fcea0e1ec2f70cd0"`) await db.query(`DROP INDEX "public"."IDX_5e414c1d12af16165881a16b63"`) @@ -182,6 +185,7 @@ module.exports = class Data1708969307321 { await db.query(`ALTER TABLE "cert_event" DROP CONSTRAINT "FK_411c2bb1469a8a96762ceb00ae6"`) await db.query(`ALTER TABLE "cert" DROP CONSTRAINT "FK_70592e488b2e75cd8a2fa798261"`) await db.query(`ALTER TABLE "cert" DROP CONSTRAINT "FK_262e29ab91c8ebc727cc518f2fb"`) + await db.query(`ALTER TABLE "cert" DROP CONSTRAINT "FK_ad35ca166ad24ecea43d7ebfca9"`) await db.query(`ALTER TABLE "smith_cert" DROP CONSTRAINT "FK_ae67cbd087fcea0e1ec2f70cd04"`) await db.query(`ALTER TABLE "smith_cert" DROP CONSTRAINT "FK_5e414c1d12af16165881a16b638"`) await db.query(`ALTER TABLE "membership_event" DROP CONSTRAINT "FK_fbbd75d84ab6cc2aafeaf37a03f"`) diff --git a/db/migrations/1709799104978-EnumsMigration.js b/db/migrations/1713861565754-EnumsMigration.js similarity index 72% rename from db/migrations/1709799104978-EnumsMigration.js rename to db/migrations/1713861565754-EnumsMigration.js index 4d1ecfc52991bce4c5e304c1c2e11af41edb4fbc..35ff70627b7becff85ec426ad7a5b00ae2101295 100644 --- a/db/migrations/1709799104978-EnumsMigration.js +++ b/db/migrations/1713861565754-EnumsMigration.js @@ -1,7 +1,7 @@ const fs = require("fs"); -module.exports = class EnumsMigration1709799104978 { - name = "EnumsMigration1709799104978"; +module.exports = class EnumsMigration1713861565754 { + name = "EnumsMigration1713861565754"; async up(db) { await db.query(fs.readFileSync("assets/sql/EnumsMigration_up.sql", "utf8")); diff --git a/db/migrations/1709218802569-udHistoryFunction.js b/db/migrations/1713861565754-udHistoryFunction.js similarity index 71% rename from db/migrations/1709218802569-udHistoryFunction.js rename to db/migrations/1713861565754-udHistoryFunction.js index 74876acdb19708bc260608cf532b660496ae5f68..d1bdafba7f095e9c0b5c6a894adf15947c189f13 100644 --- a/db/migrations/1709218802569-udHistoryFunction.js +++ b/db/migrations/1713861565754-udHistoryFunction.js @@ -1,7 +1,7 @@ const fs = require("fs"); -module.exports = class udHistoryFunction { - name = "udHistoryFunction1709218802569"; +module.exports = class udHistoryFunction1713861565754 { + name = "udHistoryFunction1713861565754"; async up(db) { await db.query(fs.readFileSync("assets/sql/udHistoryFunction_up.sql", "utf8")); diff --git a/hasura/metadata/databases/default/tables/public_cert.yaml b/hasura/metadata/databases/default/tables/public_cert.yaml index 8d3d0c00d485f31d844f7ce1300a26dbf4a3f1b3..88f4078c0ef063317295cf37234c53a5fd7beca5 100644 --- a/hasura/metadata/databases/default/tables/public_cert.yaml +++ b/hasura/metadata/databases/default/tables/public_cert.yaml @@ -8,6 +8,9 @@ object_relationships: - name: receiver using: foreign_key_constraint_on: receiver_id + - name: createdIn + using: + foreign_key_constraint_on: created_in_id array_relationships: - name: certHistory using: diff --git a/schema.graphql b/schema.graphql index b34b1e0ded7bc66b7c3fab769031d1a17355a285..79fb7d027eb2977ac520309d308709806af8b511 100644 --- a/schema.graphql +++ b/schema.graphql @@ -223,6 +223,7 @@ type Cert @entity { createdOn: Int! "the current expireOn value" # helper field to avoid looking for all CertRenewal and search for the last one expireOn: Int! + createdIn: Event! certHistory: [CertEvent!] @derivedFrom(field: "cert") } diff --git a/scripts/start_dev_docker.sh b/scripts/start_dev_docker.sh deleted file mode 100755 index 4f45d9f0aa3533e67c3e29d682447056a13aa0f3..0000000000000000000000000000000000000000 --- a/scripts/start_dev_docker.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -docker compose -f docker-compose.dev.yml up -d -# Even if Hasura container apply metadata on startup, we need to apply squid migration before apply metadata. -# The first Hasura apply will fail if correct migrations are not applied. -sqd migration:apply -sqd hasura:apply diff --git a/src/data_handler.ts b/src/data_handler.ts index 532d7e6920989e5ec01f017bf7a8dc42467a0166..4fbe7054e5b55070f3b9747d467690b655f2c6e2 100644 --- a/src/data_handler.ts +++ b/src/data_handler.ts @@ -226,6 +226,7 @@ export class DataHandler { where: { issuer: { index: issuerId }, receiver: { index: receiverId } }, }); + const eventType = await ctx.store.getOrFail(Event, event.id); if (cert == null) { const issuer = await this.getIdtyByIndexOrFail(ctx, issuerId); const receiver = await this.getIdtyByIndexOrFail(ctx, receiverId); @@ -236,6 +237,7 @@ export class DataHandler { receiver, createdOn, expireOn, + createdIn: eventType, }); // the cert has already existed, expired, and is created again // we update it accordingly @@ -243,6 +245,7 @@ export class DataHandler { cert.isActive = true; cert.createdOn = createdOn; cert.expireOn = expireOn; + cert.createdIn = eventType; } // update cert and add event @@ -267,8 +270,10 @@ export class DataHandler { relations: { issuer: true, receiver: true }, where: { issuer: { index: issuerId }, receiver: { index: receiverId } }, }); + const eventType = await ctx.store.getOrFail(Event, event.id); // update expiration date cert.expireOn = expireOn; + cert.createdIn = eventType; this.data.certification.set([issuerId, receiverId], cert); this.data.certEvent.push( new CertEvent({ @@ -286,6 +291,7 @@ export class DataHandler { const { issuerId, receiverId, blockNumber, event } = c; // should never fail because cert removal can only happen on existing cert // and cert should not be removed at their creation block + const eventType = await ctx.store.getOrFail(Event, event.id); const cert = await ctx.store.findOneOrFail(Cert, { relations: { issuer: true, receiver: true }, where: { issuer: { index: issuerId }, receiver: { index: receiverId } }, @@ -293,6 +299,7 @@ export class DataHandler { // update cert cert.isActive = false; cert.expireOn = blockNumber; + cert.createdIn = eventType; this.data.certification.set([issuerId, receiverId], cert); this.data.certEvent.push( diff --git a/src/genesis.ts b/src/genesis.ts index 72a7ba8b3d8a3f5b383f3c59e260263e08c48690..c522be527685059cb742b93f6c308b06082cfe73 100644 --- a/src/genesis.ts +++ b/src/genesis.ts @@ -107,7 +107,9 @@ export async function saveGenesis(ctx: Ctx, block: Block) { isActive: true, issuer: identities.get(parseInt(issuer_index)), receiver: identities.get(parseInt(receiver_index)), + //TODO: Set negative block number for genesis certs createdOn: 0, + createdIn: genesis_event, expireOn: expiration_block as number, }) ); diff --git a/src/model/generated/cert.model.ts b/src/model/generated/cert.model.ts index 332c7aea1ce2a6e18780ebe119fba3d7c71f685c..add3ff0e04e81ae48eabcd1f3c2dba05c0097eb1 100644 --- a/src/model/generated/cert.model.ts +++ b/src/model/generated/cert.model.ts @@ -1,5 +1,6 @@ import {Entity as Entity_, Column as Column_, PrimaryColumn as PrimaryColumn_, ManyToOne as ManyToOne_, Index as Index_, OneToMany as OneToMany_} from "typeorm" import {Identity} from "./identity.model" +import {Event} from "./event.model" import {CertEvent} from "./certEvent.model" /** @@ -40,6 +41,10 @@ export class Cert { @Column_("int4", {nullable: false}) expireOn!: number + @Index_() + @ManyToOne_(() => Event, {nullable: true}) + createdIn!: Event + @OneToMany_(() => CertEvent, e => e.cert) certHistory!: CertEvent[] }