diff --git a/db/migrations/1730204747165-Data.js b/db/migrations/1730814071971-Data.js similarity index 99% rename from db/migrations/1730204747165-Data.js rename to db/migrations/1730814071971-Data.js index a312cb2f83134cbff7d9631479e3f07df45ecadc..e479c0bd639aed9de66e5e97150b4f374d75b149 100644 --- a/db/migrations/1730204747165-Data.js +++ b/db/migrations/1730814071971-Data.js @@ -1,5 +1,5 @@ -module.exports = class Data1730204747165 { - name = 'Data1730204747165' +module.exports = class Data1730814071971 { + name = 'Data1730814071971' 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"))`) @@ -79,7 +79,7 @@ module.exports = class Data1730204747165 { await db.query(`CREATE INDEX "IDX_f4007436c1b546ede08a4fd7ab" ON "transfer" ("amount") `) await db.query(`CREATE INDEX "IDX_2a4e1dce9f72514cd28f554ee2" ON "transfer" ("event_id") `) await db.query(`CREATE INDEX "IDX_76cf30dd4464ed95ad44c5bb61" ON "transfer" ("comment_id") `) - await db.query(`CREATE TABLE "account" ("id" character varying NOT NULL, "is_active" boolean NOT NULL, "linked_identity_id" character varying, CONSTRAINT "PK_54115ee388cdb6d86bb4bf5b2ea" PRIMARY KEY ("id"))`) + await db.query(`CREATE TABLE "account" ("id" character varying NOT NULL, "created_on" integer NOT NULL, "is_active" boolean 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 "validator" ("id" character varying NOT NULL, "index" integer NOT NULL, CONSTRAINT "PK_ae0a943022c24bd60e7161e0fad" PRIMARY KEY ("id"))`) await db.query(`CREATE INDEX "IDX_49842e345355a71ff691c7a1ee" ON "validator" ("index") `) diff --git a/db/migrations/1730204867181-EnumsMigration.js b/db/migrations/1730814191993-EnumsMigration.js similarity index 72% rename from db/migrations/1730204867181-EnumsMigration.js rename to db/migrations/1730814191993-EnumsMigration.js index 346fca25d964d68bae9c4b54d41dbd283a2177c8..2c304b4e02f8f64dfb9defe4e84ecf04af433fc7 100644 --- a/db/migrations/1730204867181-EnumsMigration.js +++ b/db/migrations/1730814191993-EnumsMigration.js @@ -1,7 +1,7 @@ const fs = require("fs"); -module.exports = class EnumsMigration1730204867181 { - name = "EnumsMigration1730204867181"; +module.exports = class EnumsMigration1730814191993 { + name = "EnumsMigration1730814191993"; async up(db) { await db.query(fs.readFileSync("assets/sql/EnumsMigration_up.sql", "utf8")); diff --git a/db/migrations/1730204867181-udHistoryFunction.js b/db/migrations/1730814191993-udHistoryFunction.js similarity index 71% rename from db/migrations/1730204867181-udHistoryFunction.js rename to db/migrations/1730814191993-udHistoryFunction.js index 277bcff0c9a45d602f55c1fab969cc8f0fa94749..76a158a93707cfa2e0e6c4b82c2ba1e7369c38b3 100644 --- a/db/migrations/1730204867181-udHistoryFunction.js +++ b/db/migrations/1730814191993-udHistoryFunction.js @@ -1,7 +1,7 @@ const fs = require("fs"); -module.exports = class udHistoryFunction1730204867181 { - name = "udHistoryFunction1730204867181"; +module.exports = class udHistoryFunction1730814191993 { + name = "udHistoryFunction1730814191993"; async up(db) { await db.query(fs.readFileSync("assets/sql/udHistoryFunction_up.sql", "utf8")); diff --git a/schema.graphql b/schema.graphql index 372232b06b2c468b6f2bbcf308705a6ba99b8663..80aa5525026689fc7338bb9c9b2bbf5d07ff222f 100644 --- a/schema.graphql +++ b/schema.graphql @@ -114,6 +114,9 @@ type ItemsCounter @entity { type Account @entity { "Account address is SS58 format" id: ID! + "Block number of account creation" + # if account is created multiple times, this is the first creation block + createdOn: Int! "current account for the identity" identity: Identity @derivedFrom(field: "account") "removed identities on this account" diff --git a/src/data_handler.ts b/src/data_handler.ts index 8b2aa2194d9a2310990465af5478a8e801686db5..6c6c62968b8cbf3f00b360e4b144a9e00c3767d9 100644 --- a/src/data_handler.ts +++ b/src/data_handler.ts @@ -70,10 +70,10 @@ export class DataHandler { } // Process accounts - for (const accountId of newData.accounts) { - const newAccount = new Account({ id: accountId, isActive: true }); - this.data.accounts.set(accountId, newAccount); - ctx.log.info(`Added account ${accountId}`); + for (const accountevt of newData.accounts) { + const newAccount = new Account({ id: accountevt.address, createdOn: accountevt.blockNumber, isActive: true }); + this.data.accounts.set(accountevt.address, newAccount); + ctx.log.info(`Added account ${accountevt}`); } // Process killed accounts @@ -577,7 +577,7 @@ export class DataHandler { async handleNewAccountsApart(ctx: Ctx, newData: NewData) { // Combine account and account link sets to get unique candidates const newAccountCandidates = new Set<Address>([ - ...newData.accounts, + ...newData.accounts.map(a => a.address), ...newData.accountLink.map((link) => link.accountId), ]); @@ -595,9 +595,9 @@ export class DataHandler { ); // Filter and create accounts that don't already exist - const accountsToCreate = [...newAccountCandidates] - .filter((id) => !existingAccountIds.has(id)) - .map((id) => new Account({ id, isActive: true })); + const accountsToCreate = newData.accounts + .filter(a => !existingAccountIds.has(a.address)) + .map(a => new Account({ id: a.address, createdOn: a.blockNumber, isActive: true })); if (accountsToCreate.length > 0) { await ctx.store.insert(accountsToCreate); diff --git a/src/genesis/genesis.ts b/src/genesis/genesis.ts index 25c218fe50143676d4c24f5d80dc3cd67a1d5918..4bf77bfb2d62bc6476446448cb5b9bb63a1d5a95 100644 --- a/src/genesis/genesis.ts +++ b/src/genesis/genesis.ts @@ -139,6 +139,7 @@ export async function saveGenesis(ctx: Ctx, block: Block) { isActive, // init to null and update later to handle circular dependency linkedIdentity: null, + createdOn: 0 // TODO track block creation of v1 account }) ); if (isActive) { @@ -388,6 +389,7 @@ export async function saveGenesis(ctx: Ctx, block: Block) { accounts.set(issuer, new Account({ id: issuer, isActive: false, + createdOn: 0 // TODO track block creation of v1 account })); } if (!accounts.has(receiver)) { @@ -395,6 +397,7 @@ export async function saveGenesis(ctx: Ctx, block: Block) { accounts.set(receiver, new Account({ id: receiver, isActive: false, + createdOn: 0 // TODO track block creation of v1 account })); } } diff --git a/src/main.ts b/src/main.ts index 980ee46a5e37899dcb356d798acc118d5cc1d0b2..3b86af222278a30f48e54ba96529cbb43bbb3b99 100644 --- a/src/main.ts +++ b/src/main.ts @@ -115,7 +115,10 @@ function collectDataFromEvents(ctx: Ctx, newData: NewData) { switch (event.name) { case events_t.system.newAccount.name: { const evt = events_t.system.newAccount.v800.decode(event); - newData.accounts.push(ss58encode(evt.account)); + newData.accounts.push({ + address: ss58encode(evt.account), + blockNumber: block.header.height + }); acc.activeAccountCount += 1; acc.blockNumber = block.header.height; break; diff --git a/src/model/generated/account.model.ts b/src/model/generated/account.model.ts index 3e4928d389b11937b80e03cc96aecbdecaba199c..117e59034aa7e08274d6b6704cd9187317392b39 100644 --- a/src/model/generated/account.model.ts +++ b/src/model/generated/account.model.ts @@ -1,4 +1,4 @@ -import {Entity as Entity_, Column as Column_, PrimaryColumn as PrimaryColumn_, OneToOne as OneToOne_, OneToMany as OneToMany_, ManyToOne as ManyToOne_, Index as Index_, BooleanColumn as BooleanColumn_} from "@subsquid/typeorm-store" +import {Entity as Entity_, Column as Column_, PrimaryColumn as PrimaryColumn_, IntColumn as IntColumn_, OneToOne as OneToOne_, OneToMany as OneToMany_, ManyToOne as ManyToOne_, Index as Index_, BooleanColumn as BooleanColumn_} from "@subsquid/typeorm-store" import {Identity} from "./identity.model" import {ChangeOwnerKey} from "./changeOwnerKey.model" import {Transfer} from "./transfer.model" @@ -19,6 +19,12 @@ export class Account { @PrimaryColumn_() id!: string + /** + * Block number of account creation + */ + @IntColumn_({nullable: false}) + createdOn!: number + /** * current account for the identity */ diff --git a/src/types_custom.ts b/src/types_custom.ts index e1c6005acb7e33ba823bcb1c997eabdc227d2f82..b8d461afd1db5f1d59444eb187711c7c6fbb1a2e 100644 --- a/src/types_custom.ts +++ b/src/types_custom.ts @@ -176,7 +176,7 @@ export interface Data { // a way to group data returned from events // this contains partial data to be turned into types export interface NewData { - accounts: Address[]; + accounts: NewAccountEvent[]; killedAccounts: Address[]; validators: BlockValidator[]; populationHistories: AccPopulationHistory[]; @@ -232,6 +232,11 @@ interface UdReevalEvent { event: Event; } +interface NewAccountEvent { + blockNumber: BlockNumber; + address: Address +} + interface TransferEvent { id: string; blockNumber: BlockNumber;