From 4e1756f6a4303b73aa925a3ce9e4ce3575e48960 Mon Sep 17 00:00:00 2001 From: Marc-Aurele Besner <82244926+marc-aurele-besner@users.noreply.github.com> Date: Thu, 8 Aug 2024 08:22:29 -0400 Subject: [PATCH] rename operatorRewardEvent -> rewardEvent and add op profile --- ...16337937-Data.js => 1723119317871-Data.js} | 32 ++++++++++--------- indexers/staking-squid/schema.graphql | 16 ++++++++-- indexers/staking-squid/src/events/operator.ts | 4 +-- .../src/model/generated/index.ts | 2 +- indexers/staking-squid/src/processor.ts | 2 ++ .../staking-squid/src/storage/operator.ts | 15 ++++++--- indexers/staking-squid/src/utils/cache.ts | 8 +++-- 7 files changed, 50 insertions(+), 29 deletions(-) rename indexers/staking-squid/db/migrations/{1723116337937-Data.js => 1723119317871-Data.js} (87%) diff --git a/indexers/staking-squid/db/migrations/1723116337937-Data.js b/indexers/staking-squid/db/migrations/1723119317871-Data.js similarity index 87% rename from indexers/staking-squid/db/migrations/1723116337937-Data.js rename to indexers/staking-squid/db/migrations/1723119317871-Data.js index 7fe7d00a9..b3558344a 100644 --- a/indexers/staking-squid/db/migrations/1723116337937-Data.js +++ b/indexers/staking-squid/db/migrations/1723119317871-Data.js @@ -1,5 +1,5 @@ -module.exports = class Data1723116337937 { - name = 'Data1723116337937' +module.exports = class Data1723119317871 { + name = 'Data1723119317871' async up(db) { await db.query(`CREATE TABLE "domain" ("id" character varying NOT NULL, "sort_id" integer NOT NULL, "account_id" text NOT NULL, "name" text NOT NULL, "runtime_id" integer NOT NULL, "runtime" character varying(6) NOT NULL, "runtime_info" text, "completed_epoch" integer NOT NULL, "last_domain_block_number" integer NOT NULL, "total_deposits" numeric NOT NULL, "total_tax_collected" numeric NOT NULL, "total_rewards_collected" numeric NOT NULL, "total_transfers_in" numeric NOT NULL, "transfers_in_count" integer NOT NULL, "total_transfers_out" numeric NOT NULL, "transfers_out_count" integer NOT NULL, "total_rejected_transfers_claimed" numeric NOT NULL, "rejected_transfers_claimed_count" integer NOT NULL, "total_transfers_rejected" numeric NOT NULL, "transfers_rejected_count" integer NOT NULL, "total_volume" numeric NOT NULL, "total_consensus_storage_fee" numeric NOT NULL, "total_domain_execution_fee" numeric NOT NULL, "total_burned_balance" numeric NOT NULL, "current_total_stake" numeric NOT NULL, "current_storage_fee_deposit" numeric NOT NULL, "bundle_count" integer NOT NULL, "last_bundle_at" integer NOT NULL, "created_at" integer, "updated_at" integer, CONSTRAINT "PK_27e3ec3ea0ae02c8c5bceab3ba9" PRIMARY KEY ("id"))`) @@ -16,11 +16,12 @@ module.exports = class Data1723116337937 { await db.query(`CREATE TABLE "account" ("id" character varying NOT NULL, "total_deposits" numeric NOT NULL, "total_tax_collected" numeric NOT NULL, "created_at" integer, "updated_at" integer, CONSTRAINT "PK_54115ee388cdb6d86bb4bf5b2ea" PRIMARY KEY ("id"))`) await db.query(`CREATE INDEX "IDX_2740156ea8742b8df1ad9d9774" ON "account" ("created_at") `) await db.query(`CREATE INDEX "IDX_8bed31488e09ed64770378600b" ON "account" ("updated_at") `) - await db.query(`CREATE TABLE "operator" ("id" character varying NOT NULL, "sort_id" integer NOT NULL, "account_id" text NOT NULL, "domain_id" text NOT NULL, "signing_key" text NOT NULL, "minimum_nominator_stake" numeric NOT NULL, "nomination_tax" integer NOT NULL, "current_total_stake" numeric NOT NULL, "current_storage_fee_deposit" numeric NOT NULL, "current_epoch_rewards" numeric NOT NULL, "current_total_shares" numeric NOT NULL, "total_deposits" numeric NOT NULL, "total_tax_collected" numeric NOT NULL, "total_rewards_collected" numeric NOT NULL, "total_transfers_in" numeric NOT NULL, "transfers_in_count" integer NOT NULL, "total_transfers_out" numeric NOT NULL, "transfers_out_count" integer NOT NULL, "total_rejected_transfers_claimed" numeric NOT NULL, "rejected_transfers_claimed_count" integer NOT NULL, "total_transfers_rejected" numeric NOT NULL, "transfers_rejected_count" integer NOT NULL, "total_volume" numeric NOT NULL, "total_consensus_storage_fee" numeric NOT NULL, "total_domain_execution_fee" numeric NOT NULL, "total_burned_balance" numeric NOT NULL, "raw_status" text, "status" character varying(15) NOT NULL, "active_epoch_count" integer NOT NULL, "bundle_count" integer NOT NULL, "last_bundle_at" integer NOT NULL, "created_at" integer, "updated_at" integer, CONSTRAINT "PK_8b950e1572745d9f69be7748ae8" PRIMARY KEY ("id"))`) + await db.query(`CREATE TABLE "operator" ("id" character varying NOT NULL, "sort_id" integer NOT NULL, "account_id" text NOT NULL, "domain_id" text NOT NULL, "signing_key" text NOT NULL, "minimum_nominator_stake" numeric NOT NULL, "nomination_tax" integer NOT NULL, "name" text NOT NULL, "website" text, "discord" text, "github" text, "twitter" text, "current_total_stake" numeric NOT NULL, "current_storage_fee_deposit" numeric NOT NULL, "current_epoch_rewards" numeric NOT NULL, "current_total_shares" numeric NOT NULL, "raw_status" text, "total_deposits" numeric NOT NULL, "total_tax_collected" numeric NOT NULL, "total_rewards_collected" numeric NOT NULL, "total_transfers_in" numeric NOT NULL, "transfers_in_count" integer NOT NULL, "total_transfers_out" numeric NOT NULL, "transfers_out_count" integer NOT NULL, "total_rejected_transfers_claimed" numeric NOT NULL, "rejected_transfers_claimed_count" integer NOT NULL, "total_transfers_rejected" numeric NOT NULL, "transfers_rejected_count" integer NOT NULL, "total_volume" numeric NOT NULL, "total_consensus_storage_fee" numeric NOT NULL, "total_domain_execution_fee" numeric NOT NULL, "total_burned_balance" numeric NOT NULL, "active_epoch_count" integer NOT NULL, "bundle_count" integer NOT NULL, "status" character varying(15) NOT NULL, "last_bundle_at" integer NOT NULL, "created_at" integer, "updated_at" integer, CONSTRAINT "PK_8b950e1572745d9f69be7748ae8" PRIMARY KEY ("id"))`) await db.query(`CREATE INDEX "IDX_ed3a1bcef6df98998f07a571a7" ON "operator" ("sort_id") `) await db.query(`CREATE INDEX "IDX_91b197ab29ad85b5e616289ea0" ON "operator" ("account_id") `) await db.query(`CREATE INDEX "IDX_1c800426a1f738c1b202ff839f" ON "operator" ("domain_id") `) await db.query(`CREATE INDEX "IDX_51b6c3609906ff3cd25e39e1b2" ON "operator" ("signing_key") `) + await db.query(`CREATE INDEX "IDX_b383ed84b5891bd42be1d2eefd" ON "operator" ("name") `) await db.query(`CREATE INDEX "IDX_df2e0bb74daa727ab46b3292b0" ON "operator" ("total_volume") `) await db.query(`CREATE INDEX "IDX_c7fd0bf382a9832cf1db87827c" ON "operator" ("status") `) await db.query(`CREATE INDEX "IDX_d6260ed02d20cf8231ebb742d6" ON "operator" ("created_at") `) @@ -66,12 +67,12 @@ module.exports = class Data1723116337937 { await db.query(`CREATE INDEX "IDX_2fff22e92b7b71ed2f39466e57" ON "operator_unlocked_funds" ("nominator_id") `) await db.query(`CREATE INDEX "IDX_48c8e45b0ff8c212f11e4a68df" ON "operator_unlocked_funds" ("timestamp") `) await db.query(`CREATE INDEX "IDX_f01f1314fe38bc670d2a48fe1a" ON "operator_unlocked_funds" ("extrinsic_hash") `) - await db.query(`CREATE TABLE "operator_reward_event" ("id" character varying NOT NULL, "domain_id" text NOT NULL, "operator_id" text NOT NULL, "amount" numeric NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, "block_number" integer NOT NULL, "extrinsic_hash" text NOT NULL, CONSTRAINT "PK_721a9f907ad1f01a5abed1f2e8e" PRIMARY KEY ("id"))`) - await db.query(`CREATE INDEX "IDX_bf9ca379132cf6ba98f9073986" ON "operator_reward_event" ("domain_id") `) - await db.query(`CREATE INDEX "IDX_b9cf23c6256a9fc7e01a271376" ON "operator_reward_event" ("operator_id") `) - await db.query(`CREATE INDEX "IDX_2b8b8fd9152da4d7ba4b71080c" ON "operator_reward_event" ("timestamp") `) - await db.query(`CREATE INDEX "IDX_d878c755d920f1be253bad97dd" ON "operator_reward_event" ("block_number") `) - await db.query(`CREATE INDEX "IDX_83b9c467963de152d3e83dcf58" ON "operator_reward_event" ("extrinsic_hash") `) + await db.query(`CREATE TABLE "reward_event" ("id" character varying NOT NULL, "domain_id" text NOT NULL, "operator_id" text NOT NULL, "amount" numeric NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, "block_number" integer NOT NULL, "extrinsic_hash" text NOT NULL, CONSTRAINT "PK_212058fe00a4e4ad6f433833992" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_c58ade91dd87782e5587dea498" ON "reward_event" ("domain_id") `) + await db.query(`CREATE INDEX "IDX_df32138995e155bfae4999ec17" ON "reward_event" ("operator_id") `) + await db.query(`CREATE INDEX "IDX_32c335d826e7606e7dec0bcd59" ON "reward_event" ("timestamp") `) + await db.query(`CREATE INDEX "IDX_dcefc6529930bf025676463725" ON "reward_event" ("block_number") `) + await db.query(`CREATE INDEX "IDX_53ac1d5bf31f15640e4d54820a" ON "reward_event" ("extrinsic_hash") `) await db.query(`CREATE TABLE "stats" ("id" character varying NOT NULL, "block_number" integer NOT NULL, "total_staked" numeric NOT NULL, "total_fees" numeric NOT NULL, "total_deposits" numeric NOT NULL, "total_withdrawals" numeric NOT NULL, "all_time_high_staked" numeric NOT NULL, "domains_count" integer NOT NULL, "operators_count" integer NOT NULL, "active_operators_count" integer NOT NULL, "slashed_operators_count" integer NOT NULL, "nominators_count" integer NOT NULL, "deposits_count" integer NOT NULL, "withdrawals_count" integer NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, CONSTRAINT "PK_c76e93dfef28ba9b6942f578ab1" PRIMARY KEY ("id"))`) await db.query(`CREATE INDEX "IDX_0b3890ae3ba62ee77fe94af26e" ON "stats" ("block_number") `) await db.query(`CREATE INDEX "IDX_ea4b2bcf5920a1b06f4454bb91" ON "stats" ("timestamp") `) @@ -108,6 +109,7 @@ module.exports = class Data1723116337937 { await db.query(`DROP INDEX "public"."IDX_91b197ab29ad85b5e616289ea0"`) await db.query(`DROP INDEX "public"."IDX_1c800426a1f738c1b202ff839f"`) await db.query(`DROP INDEX "public"."IDX_51b6c3609906ff3cd25e39e1b2"`) + await db.query(`DROP INDEX "public"."IDX_b383ed84b5891bd42be1d2eefd"`) await db.query(`DROP INDEX "public"."IDX_df2e0bb74daa727ab46b3292b0"`) await db.query(`DROP INDEX "public"."IDX_c7fd0bf382a9832cf1db87827c"`) await db.query(`DROP INDEX "public"."IDX_d6260ed02d20cf8231ebb742d6"`) @@ -153,12 +155,12 @@ module.exports = class Data1723116337937 { await db.query(`DROP INDEX "public"."IDX_2fff22e92b7b71ed2f39466e57"`) await db.query(`DROP INDEX "public"."IDX_48c8e45b0ff8c212f11e4a68df"`) await db.query(`DROP INDEX "public"."IDX_f01f1314fe38bc670d2a48fe1a"`) - await db.query(`DROP TABLE "operator_reward_event"`) - await db.query(`DROP INDEX "public"."IDX_bf9ca379132cf6ba98f9073986"`) - await db.query(`DROP INDEX "public"."IDX_b9cf23c6256a9fc7e01a271376"`) - await db.query(`DROP INDEX "public"."IDX_2b8b8fd9152da4d7ba4b71080c"`) - await db.query(`DROP INDEX "public"."IDX_d878c755d920f1be253bad97dd"`) - await db.query(`DROP INDEX "public"."IDX_83b9c467963de152d3e83dcf58"`) + await db.query(`DROP TABLE "reward_event"`) + await db.query(`DROP INDEX "public"."IDX_c58ade91dd87782e5587dea498"`) + await db.query(`DROP INDEX "public"."IDX_df32138995e155bfae4999ec17"`) + await db.query(`DROP INDEX "public"."IDX_32c335d826e7606e7dec0bcd59"`) + await db.query(`DROP INDEX "public"."IDX_dcefc6529930bf025676463725"`) + await db.query(`DROP INDEX "public"."IDX_53ac1d5bf31f15640e4d54820a"`) await db.query(`DROP TABLE "stats"`) await db.query(`DROP INDEX "public"."IDX_0b3890ae3ba62ee77fe94af26e"`) await db.query(`DROP INDEX "public"."IDX_ea4b2bcf5920a1b06f4454bb91"`) diff --git a/indexers/staking-squid/schema.graphql b/indexers/staking-squid/schema.graphql index 6c70d90cd..719c6e373 100644 --- a/indexers/staking-squid/schema.graphql +++ b/indexers/staking-squid/schema.graphql @@ -56,14 +56,24 @@ type Operator @entity { id: ID! @index sortId: Int! @index accountId: String! @index + # creation args domainId: String! @index signingKey: String! @index minimumNominatorStake: BigInt! nominationTax: Int! + # public profile + name: String! @index + website: String + discord: String + github: String + twitter: String + # chain state currentTotalStake: BigInt! currentStorageFeeDeposit: BigInt! currentEpochRewards: BigInt! currentTotalShares: BigInt! + rawStatus: String + # increments totalDeposits: BigInt! totalTaxCollected: BigInt! totalRewardsCollected: BigInt! @@ -79,10 +89,10 @@ type Operator @entity { totalConsensusStorageFee: BigInt! totalDomainExecutionFee: BigInt! totalBurnedBalance: BigInt! - rawStatus: String - status: OperatorStatus! @index activeEpochCount: Int! bundleCount: Int! + # status and timestamps + status: OperatorStatus! @index lastBundleAt: Int! createdAt: Int @index updatedAt: Int @index @@ -195,7 +205,7 @@ type OperatorUnlockedFunds @entity { amount: BigInt! } -type OperatorRewardEvent @entity { +type RewardEvent @entity { id: ID! @index domainId: String! @index operatorId: String! @index diff --git a/indexers/staking-squid/src/events/operator.ts b/indexers/staking-squid/src/events/operator.ts index 8d9dcfd76..d2a319c1f 100644 --- a/indexers/staking-squid/src/events/operator.ts +++ b/indexers/staking-squid/src/events/operator.ts @@ -2,7 +2,7 @@ import { NominatorStatus, OperatorStatus } from "../model"; import type { CtxBlock, CtxEvent, CtxExtrinsic } from "../processor"; import { createDeposit, - createOperatorRewardEvent, + createRewardEvent, getOrCreateAccount, getOrCreateDomain, getOrCreateNominator, @@ -155,7 +155,7 @@ export function processOperatorRewardedEvent( domain.totalRewardsCollected += amount; cache.domains.set(domain.id, domain); - const operatorRewardedEvent = createOperatorRewardEvent(block, extrinsic, { + const operatorRewardedEvent = createRewardEvent(block, extrinsic, { operatorId: operator.id, domainId: operator.domainId, amount, diff --git a/indexers/staking-squid/src/model/generated/index.ts b/indexers/staking-squid/src/model/generated/index.ts index 99a55916c..5842bad53 100644 --- a/indexers/staking-squid/src/model/generated/index.ts +++ b/indexers/staking-squid/src/model/generated/index.ts @@ -12,7 +12,7 @@ export * from "./_depositStatus" export * from "./withdrawal.model" export * from "./_withdrawalStatus" export * from "./operatorUnlockedFunds.model" -export * from "./operatorRewardEvent.model" +export * from "./rewardEvent.model" export * from "./stats.model" export * from "./statsPerDomain.model" export * from "./statsPerOperator.model" diff --git a/indexers/staking-squid/src/processor.ts b/indexers/staking-squid/src/processor.ts index a04b9f4ee..c11837751 100644 --- a/indexers/staking-squid/src/processor.ts +++ b/indexers/staking-squid/src/processor.ts @@ -58,6 +58,8 @@ export const processor = new SubstrateBatchProcessor() events.domains.storageFeeDeposited.name, // bundle events.domains.bundleStored.name, + // unlock + events.domains.fundsUnlocked.name, // rewards and slashing events.domains.operatorRewarded.name, events.domains.operatorSlashed.name, diff --git a/indexers/staking-squid/src/storage/operator.ts b/indexers/staking-squid/src/storage/operator.ts index ce6ca677b..0aa63dd99 100644 --- a/indexers/staking-squid/src/storage/operator.ts +++ b/indexers/staking-squid/src/storage/operator.ts @@ -1,5 +1,5 @@ import { randomUUID } from "crypto"; -import { Operator, OperatorRewardEvent, OperatorStatus } from "../model"; +import { Operator, OperatorStatus, RewardEvent } from "../model"; import type { CtxBlock, CtxExtrinsic } from "../processor"; import { getBlockNumber, getTimestamp, operatorUID } from "../utils"; import { Cache } from "../utils/cache"; @@ -15,6 +15,11 @@ export const createOperator = ( signingKey: "0x", minimumNominatorStake: BigInt(0), nominationTax: 0, + name: "", + website: "", + discord: "", + github: "", + twitter: "", currentTotalStake: BigInt(0), currentStorageFeeDeposit: BigInt(0), currentEpochRewards: BigInt(0), @@ -59,12 +64,12 @@ export const getOrCreateOperator = ( return operator; }; -export const createOperatorRewardEvent = ( +export const createRewardEvent = ( block: CtxBlock, extrinsic: CtxExtrinsic, - props: Partial -): OperatorRewardEvent => - new OperatorRewardEvent({ + props: Partial +): RewardEvent => + new RewardEvent({ id: randomUUID(), ...props, blockNumber: getBlockNumber(block), diff --git a/indexers/staking-squid/src/utils/cache.ts b/indexers/staking-squid/src/utils/cache.ts index e86314c66..dd1e631bf 100644 --- a/indexers/staking-squid/src/utils/cache.ts +++ b/indexers/staking-squid/src/utils/cache.ts @@ -8,7 +8,7 @@ import { Domain, Nominator, Operator, - OperatorRewardEvent, + RewardEvent, Stats, StatsPerDomain, StatsPerOperator, @@ -28,7 +28,7 @@ export type TemporaryCache = { withdrawals: Map; bundles: Map; bundleAuthors: Map; - operatorRewardedEvents: Map; + operatorRewardedEvents: Map; stats: Map; statsPerDomain: Map; statsPerOperator: Map; @@ -97,7 +97,9 @@ export const save = async (ctx: Ctx, cache: Cache) => { if (!cache.isModified) return; await Promise.all( - Object.keys(cache).map((k) => saveEntry(ctx, cache, k as keyof Cache)) + Object.keys(cache).map((k) => + k !== "isModified" ? saveEntry(ctx, cache, k as keyof Cache) : null + ) ); // Clear the cache for entries not needed for reference