diff --git a/README.md b/README.md
index 1534927aa..f0a18c356 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
# Astral
-- [Astral Block Explorer](https://explorer.subspace.network/) Astral Block Explorer
+- [Astral Block Explorer](https://explorer.autonomys.xyz/) Astral Block Explorer
- [Astral Subsquid Playground](https://squid.gemini-3g.subspace.network/graphql) Astral Subspace SubSquid
- [Health Check](https://uptime.subspace.network/status/network) Subspace Network Status Page
diff --git a/explorer/next.config.js b/explorer/next.config.js
index 21d355cc3..626c76920 100644
--- a/explorer/next.config.js
+++ b/explorer/next.config.js
@@ -6,7 +6,7 @@ const nextConfig = {
remotePatterns: [
{
protocol: 'https',
- hostname: 'docs.subspace.network',
+ hostname: 'docs.autonomys.xyz',
port: '',
pathname: '**',
},
diff --git a/explorer/src/components/Farming/index.tsx b/explorer/src/components/Farming/index.tsx
index 013220a19..d28d0f5c2 100644
--- a/explorer/src/components/Farming/index.tsx
+++ b/explorer/src/components/Farming/index.tsx
@@ -187,7 +187,7 @@ export const DownloadPage: FC = () => {
alt='Space Acres Screenshot Installation'
width={800}
height={400}
- src='https://docs.subspace.network/assets/images/space-acres-setup-7-3490cba2e75635efdea0006d06da9936.png'
+ src='https://docs.autonomys.xyz/assets/images/space-acres-setup-7-3490cba2e75635efdea0006d06da9936.png'
className='mx-auto'
/>
@@ -198,8 +198,6 @@ export const DownloadPage: FC = () => {
By contributing storage and compute to the network, you play a crucial role in securing
it, while also earning rewards.
-
-
diff --git a/explorer/src/components/WalletSideKick/PendingTransactions.tsx b/explorer/src/components/WalletSideKick/PendingTransactions.tsx
index 774ede227..7ed7b0f00 100644
--- a/explorer/src/components/WalletSideKick/PendingTransactions.tsx
+++ b/explorer/src/components/WalletSideKick/PendingTransactions.tsx
@@ -160,7 +160,10 @@ export const PendingTransactions: FC
= ({
-
+
handleRemove(tx)} />
diff --git a/explorer/src/components/common/StatusIcon.tsx b/explorer/src/components/common/StatusIcon.tsx
index 50c2e95f4..32dab0f34 100644
--- a/explorer/src/components/common/StatusIcon.tsx
+++ b/explorer/src/components/common/StatusIcon.tsx
@@ -1,14 +1,16 @@
-import { CheckCircleIcon, ClockIcon } from '@heroicons/react/24/outline'
+import { CheckCircleIcon, ClockIcon, XCircleIcon } from '@heroicons/react/24/outline'
import { FC } from 'react'
type Props = {
status: boolean
+ isPending?: boolean
}
-export const StatusIcon: FC = ({ status }) => {
+export const StatusIcon: FC = ({ status, isPending }) => {
+ if (isPending) return
return status ? (
) : (
-
+
)
}
diff --git a/explorer/src/constants/metadata.ts b/explorer/src/constants/metadata.ts
index d60959877..9003bd9cf 100644
--- a/explorer/src/constants/metadata.ts
+++ b/explorer/src/constants/metadata.ts
@@ -3,7 +3,7 @@ const organization = 'Subspace Labs'
const description = 'Subspace Labs Gemini Block Explorer'
const keywords =
'Subspace, Subspace Network, Subspace Explorer, Subspace Labs, Subspace Labs Gemini, Subspace Labs Gemini Block Explorer'
-export const url = process.env.NEXTAUTH_URL || 'https://explorer.subspace.network'
+export const url = process.env.NEXTAUTH_URL || 'https://explorer.autonomys.xyz'
const twitter = '@SubspaceLabs'
const images = {
url: url + '/images/share.png',
diff --git a/explorer/src/constants/routes.ts b/explorer/src/constants/routes.ts
index a64087e3e..403d7df63 100644
--- a/explorer/src/constants/routes.ts
+++ b/explorer/src/constants/routes.ts
@@ -55,9 +55,9 @@ export const EXTERNAL_ROUTES = {
forum: 'https://forum.autonomys.xyz/',
gemini2guide:
'https://forum.autonomys.xyz/t/how-to-check-your-balance-for-gemini-ii-incentivized-testnet/1081',
- docs: 'https://docs.subspace.network/',
+ docs: 'https://docs.autonomys.xyz/',
operatorDocs:
- 'https://docs.subspace.network/docs/farming-&-staking/staking/operators/register-operator',
+ 'https://docs.autonomys.xyz/docs/farming-&-staking/staking/operators/register-operator',
social: {
twitter: 'https://x.com/AutonomysNet',
discord: 'https://discord.gg/subspace-network',
diff --git a/explorer/src/hooks/useConsensusData.ts b/explorer/src/hooks/useConsensusData.ts
index 241d64cdf..231cbc103 100644
--- a/explorer/src/hooks/useConsensusData.ts
+++ b/explorer/src/hooks/useConsensusData.ts
@@ -2,7 +2,7 @@ import useWallet from 'hooks/useWallet'
import { useCallback } from 'react'
import { useConsensusStates } from 'states/consensus'
import {
- ConfirmedDomainBlock,
+ ConfirmedDomainExecutionReceipt,
DomainRegistry,
DomainStakingSummary,
PendingStakingOperationCount,
@@ -17,7 +17,7 @@ export const useConsensusData = () => {
setSystem,
setDomainRegistry,
setDomainStakingSummary,
- setLatestConfirmedDomainBlock,
+ setLatestConfirmedDomainExecutionReceipt,
setNominatorCount,
setOperatorIdOwner,
setOperators,
@@ -41,7 +41,7 @@ export const useConsensusData = () => {
// domains
domainRegistry,
domainStakingSummary,
- latestConfirmedDomainBlock,
+ latestConfirmedDomainExecutionReceipt,
nominatorCount,
operatorIdOwner,
operators,
@@ -53,9 +53,10 @@ export const useConsensusData = () => {
// system
api.rpc.system.chain(),
api.rpc.system.name(),
+ // domains
api.query.domains.domainRegistry.entries(),
api.query.domains.domainStakingSummary.entries(),
- api.query.domains.latestConfirmedDomainBlock.entries(),
+ api.query.domains.latestConfirmedDomainExecutionReceipt.entries(),
api.query.domains.nominatorCount.entries(),
api.query.domains.operatorIdOwner.entries(),
api.query.domains.operators.entries(),
@@ -106,10 +107,10 @@ export const useConsensusData = () => {
setDomainStakingSummary(
domainStakingSummary.map((domain) => domain[1].toJSON() as DomainStakingSummary),
)
- setLatestConfirmedDomainBlock(
- latestConfirmedDomainBlock.map((domainBlock) => ({
+ setLatestConfirmedDomainExecutionReceipt(
+ latestConfirmedDomainExecutionReceipt.map((domainBlock) => ({
id: parseInt((domainBlock[0].toHuman() as string[])[0]),
- ...(domainBlock[1].toJSON() as Omit),
+ ...(domainBlock[1].toJSON() as Omit),
})),
)
setNominatorCount(
diff --git a/explorer/src/states/consensus.ts b/explorer/src/states/consensus.ts
index 84dc83f86..3dbd37d48 100644
--- a/explorer/src/states/consensus.ts
+++ b/explorer/src/states/consensus.ts
@@ -1,6 +1,6 @@
import type { Deposit, Withdrawal } from '@autonomys/auto-consensus'
import {
- ConfirmedDomainBlock,
+ ConfirmedDomainExecutionReceipt,
Domain,
DomainRegistry,
DomainStakingSummary,
@@ -28,7 +28,7 @@ export interface ConsensusDefaultState {
// domains
domainRegistry: DomainRegistry[]
domainStakingSummary: DomainStakingSummary[]
- latestConfirmedDomainBlock: ConfirmedDomainBlock[]
+ latestConfirmedDomainExecutionReceipt: ConfirmedDomainExecutionReceipt[]
// latestSubmittedER: LatestSubmittedER[]
nominatorCount: NominatorCount[]
operatorIdOwner: OperatorIdOwner[]
@@ -51,7 +51,9 @@ interface ConsensusState extends ConsensusDefaultState {
setSystem: (params: { chain: string; name: string }) => void
setDomainRegistry: (domainRegistry: DomainRegistry[]) => void
setDomainStakingSummary: (domainStakingSummary: DomainStakingSummary[]) => void
- setLatestConfirmedDomainBlock: (latestConfirmedDomainBlock: ConfirmedDomainBlock[]) => void
+ setLatestConfirmedDomainExecutionReceipt: (
+ latestConfirmedDomainExecutionReceipt: ConfirmedDomainExecutionReceipt[],
+ ) => void
setNominatorCount: (nominatorCount: NominatorCount[]) => void
setOperatorIdOwner: (operatorIdOwner: OperatorIdOwner[]) => void
setOperators: (operators: Operators[]) => void
@@ -77,7 +79,7 @@ const initialState: ConsensusDefaultState = {
// domains
domainRegistry: [],
domainStakingSummary: [],
- latestConfirmedDomainBlock: [],
+ latestConfirmedDomainExecutionReceipt: [],
// latestSubmittedER: [],
nominatorCount: [],
operatorIdOwner: [],
@@ -104,8 +106,8 @@ export const useConsensusStates = create()(
setSystem: (params) => set(() => ({ chain: params.chain, name: params.name })),
setDomainRegistry: (domainRegistry) => set(() => ({ domainRegistry })),
setDomainStakingSummary: (domainStakingSummary) => set(() => ({ domainStakingSummary })),
- setLatestConfirmedDomainBlock: (latestConfirmedDomainBlock) =>
- set(() => ({ latestConfirmedDomainBlock })),
+ setLatestConfirmedDomainExecutionReceipt: (latestConfirmedDomainExecutionReceipt) =>
+ set(() => ({ latestConfirmedDomainExecutionReceipt })),
setNominatorCount: (nominatorCount) => set(() => ({ nominatorCount })),
setOperatorIdOwner: (operatorIdOwner) => set(() => ({ operatorIdOwner })),
setOperators: (operators) => set(() => ({ operators })),
diff --git a/explorer/src/types/consensus.ts b/explorer/src/types/consensus.ts
index f0c8fe1c1..8355738f9 100644
--- a/explorer/src/types/consensus.ts
+++ b/explorer/src/types/consensus.ts
@@ -56,13 +56,9 @@ export type DomainStakingSummary = {
}
}
-export type ConfirmedDomainBlock = {
+export type ConfirmedDomainExecutionReceipt = {
id: number
- blockNumber: number
- blockHash: string
- parentBlockReceiptHash: string
- stateRoot: string
- extrinsicsRoot: string
+ domainBlockNumber: number
}
export type NominatorCount = {
diff --git a/explorer/src/utils/auth/providers/nova.ts b/explorer/src/utils/auth/providers/nova.ts
index c98789203..bfc3a1bc6 100644
--- a/explorer/src/utils/auth/providers/nova.ts
+++ b/explorer/src/utils/auth/providers/nova.ts
@@ -30,7 +30,7 @@ export const Nova = () => {
const verifyParams: VerifyParams = {
signature,
- domain: 'subspace.network',
+ domain: 'autonomys.xyz',
nonce: await getCsrfToken({ req }),
}
diff --git a/indexers/staking-squid/README.md b/indexers/staking-squid/README.md
index 8b6a93548..d23790025 100644
--- a/indexers/staking-squid/README.md
+++ b/indexers/staking-squid/README.md
@@ -1,7 +1,7 @@
# Staking squid
Our Staking Indexer using [Squid](https://subsquid.io).
-It is in use at [Astral - Staking](https://explorer.subspace.network/gemini-3h/staking) Autonomus Explorer, Staking section.
+It is in use at [Astral - Staking](https://explorer.autonomys.xyz/gemini-3h/staking) Autonomys Explorer, Staking section.
## Summary
diff --git a/indexers/staking-squid/db/migrations/1721778314620-Data.js b/indexers/staking-squid/db/migrations/1722613051042-Data.js
similarity index 55%
rename from indexers/staking-squid/db/migrations/1721778314620-Data.js
rename to indexers/staking-squid/db/migrations/1722613051042-Data.js
index 68d44ce9d..3be75732c 100644
--- a/indexers/staking-squid/db/migrations/1721778314620-Data.js
+++ b/indexers/staking-squid/db/migrations/1722613051042-Data.js
@@ -1,132 +1,132 @@
-module.exports = class Data1721778314620 {
- name = 'Data1721778314620'
+module.exports = class Data1722613051042 {
+ name = 'Data1722613051042'
async up(db) {
- await db.query(`CREATE TABLE "withdrawal" ("id" character varying NOT NULL, "block_number" integer NOT NULL, "account" text NOT NULL, "shares" numeric NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, "extrinsic_hash" text NOT NULL, "status" character varying(8) NOT NULL, "operator_id" character varying, "nominator_id" character varying, CONSTRAINT "PK_840e247aaad3fbd4e18129122a2" PRIMARY KEY ("id"))`)
- await db.query(`CREATE INDEX "IDX_e8ac24b4a9b9657cd27289feea" ON "withdrawal" ("block_number") `)
- await db.query(`CREATE INDEX "IDX_25c7ac5a7731ac3ce7982bef67" ON "withdrawal" ("account") `)
- await db.query(`CREATE INDEX "IDX_d5f5ce8abff91d6485c4f84e57" ON "withdrawal" ("operator_id") `)
- await db.query(`CREATE INDEX "IDX_09c9cf2ad9a4f3b674540dbfcf" ON "withdrawal" ("nominator_id") `)
- await db.query(`CREATE INDEX "IDX_e2749aaf8ba367458c360a7c73" ON "withdrawal" ("timestamp") `)
- await db.query(`CREATE INDEX "IDX_9c33f1820b02bef49172b9883f" ON "withdrawal" ("extrinsic_hash") `)
- await db.query(`CREATE INDEX "IDX_4028ed4e39f5c919fc3317882b" ON "withdrawal" ("status") `)
- await db.query(`CREATE TABLE "nominator" ("id" character varying NOT NULL, "account" text NOT NULL, "shares" numeric NOT NULL, "total_deposits" numeric NOT NULL, "deposits_count" integer NOT NULL, "withdrawals_count" integer NOT NULL, "status" character varying(12) NOT NULL, "created_at" integer, "updated_at" integer, "operator_id" character varying, CONSTRAINT "PK_7489b7a79b066f2660eab25f60b" PRIMARY KEY ("id"))`)
- await db.query(`CREATE INDEX "IDX_ef8faa81be0a51d54fc727b9fb" ON "nominator" ("account") `)
+ await db.query(`CREATE TABLE "domain" ("id" character varying NOT NULL, "sort_id" integer NOT NULL, "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, "current_total_stake" numeric NOT NULL, "current_storage_fee_deposit" numeric NOT NULL, "created_at" integer, "updated_at" integer, CONSTRAINT "PK_27e3ec3ea0ae02c8c5bceab3ba9" PRIMARY KEY ("id"))`)
+ await db.query(`CREATE INDEX "IDX_c1e90b3654ffe0a5544e502edb" ON "domain" ("sort_id") `)
+ await db.query(`CREATE INDEX "IDX_80867983eb3f6e204acfea4214" ON "domain" ("completed_epoch") `)
+ await db.query(`CREATE INDEX "IDX_e3a1b94f40001682587d9b0a3d" ON "domain" ("last_domain_block_number") `)
+ await db.query(`CREATE INDEX "IDX_35b49bec8ab1e3864de09a60d6" ON "domain" ("created_at") `)
+ await db.query(`CREATE INDEX "IDX_c3ac554ab7a2ed97d9a0af4083" ON "domain" ("updated_at") `)
+ 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, "raw_status" text, "status" character varying(15) 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 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_c7fd0bf382a9832cf1db87827c" ON "operator" ("status") `)
+ await db.query(`CREATE INDEX "IDX_d6260ed02d20cf8231ebb742d6" ON "operator" ("created_at") `)
+ await db.query(`CREATE INDEX "IDX_d6d18ca05472785030a7a3963b" ON "operator" ("updated_at") `)
+ await db.query(`CREATE TABLE "nominator" ("id" character varying NOT NULL, "account_id" text NOT NULL, "domain_id" text NOT NULL, "operator_id" text NOT NULL, "shares" numeric NOT NULL, "total_deposits" numeric NOT NULL, "status" character varying(12) NOT NULL, "created_at" integer, "updated_at" integer, CONSTRAINT "PK_7489b7a79b066f2660eab25f60b" PRIMARY KEY ("id"))`)
+ await db.query(`CREATE INDEX "IDX_917636e6d1130ea9506eaeafef" ON "nominator" ("account_id") `)
+ await db.query(`CREATE INDEX "IDX_b017cafe03fa79059bd8164c4e" ON "nominator" ("domain_id") `)
await db.query(`CREATE INDEX "IDX_14374f281ccb6e72c55dab3c20" ON "nominator" ("operator_id") `)
await db.query(`CREATE INDEX "IDX_43aeeb4c46d83dd78aa564c1b1" ON "nominator" ("status") `)
await db.query(`CREATE INDEX "IDX_7093d62ba7e5a6387a686e607e" ON "nominator" ("created_at") `)
await db.query(`CREATE INDEX "IDX_9ebc942736e76bde99ee21452f" ON "nominator" ("updated_at") `)
- await db.query(`CREATE TABLE "deposit" ("id" character varying NOT NULL, "block_number" integer NOT NULL, "account" text NOT NULL, "amount" numeric NOT NULL, "storage_fee_deposit" numeric NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, "extrinsic_hash" text NOT NULL, "status" character varying(9) NOT NULL, "operator_id" character varying, "nominator_id" character varying, CONSTRAINT "PK_6654b4be449dadfd9d03a324b61" PRIMARY KEY ("id"))`)
+ await db.query(`CREATE TABLE "deposit" ("id" character varying NOT NULL, "block_number" integer NOT NULL, "account_id" text NOT NULL, "domain_id" text NOT NULL, "operator_id" text NOT NULL, "nominator_id" text NOT NULL, "amount" numeric NOT NULL, "storage_fee_deposit" numeric NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, "extrinsic_hash" text NOT NULL, "status" character varying(9) NOT NULL, CONSTRAINT "PK_6654b4be449dadfd9d03a324b61" PRIMARY KEY ("id"))`)
await db.query(`CREATE INDEX "IDX_230a90fc5a10c7ac5ac35397d2" ON "deposit" ("block_number") `)
- await db.query(`CREATE INDEX "IDX_f3abde1e7f8d7ca5102e376219" ON "deposit" ("account") `)
+ await db.query(`CREATE INDEX "IDX_9ced91570695137ec1d60c1a61" ON "deposit" ("account_id") `)
+ await db.query(`CREATE INDEX "IDX_8dc544cfa89fb544beea034396" ON "deposit" ("domain_id") `)
await db.query(`CREATE INDEX "IDX_c2f2cfaa2b294c75d38a57e380" ON "deposit" ("operator_id") `)
await db.query(`CREATE INDEX "IDX_b673efd4ec207b203e4d06abe9" ON "deposit" ("nominator_id") `)
await db.query(`CREATE INDEX "IDX_a37222607a86476fa124313c51" ON "deposit" ("timestamp") `)
await db.query(`CREATE INDEX "IDX_b1d1dadac59ff00a27b4ef18cf" ON "deposit" ("extrinsic_hash") `)
await db.query(`CREATE INDEX "IDX_6f250bd43f2f631fcb2f589200" ON "deposit" ("status") `)
- await db.query(`CREATE TABLE "operator_reward_event" ("id" character varying NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, "block_number" integer NOT NULL, "extrinsic_hash" text NOT NULL, "amount" numeric NOT NULL, "operator_id" character varying, CONSTRAINT "PK_721a9f907ad1f01a5abed1f2e8e" PRIMARY KEY ("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 "operator_fees_earned" ("id" character varying NOT NULL, "amount" numeric NOT NULL, "updated_at" integer NOT NULL, "operator_id" character varying, CONSTRAINT "PK_65191b997e44f43ec2c5d68c7e1" PRIMARY KEY ("id"))`)
- await db.query(`CREATE INDEX "IDX_c9dda7e56175bc755c449c5e02" ON "operator_fees_earned" ("operator_id") `)
- await db.query(`CREATE TABLE "operator" ("id" character varying NOT NULL, "domain_id" integer NOT NULL, "operator_id" integer NOT NULL, "signing_key" text NOT NULL, "owner" 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, "raw_status" text, "status" character varying(12) NOT NULL, "nominators_count" integer NOT NULL, "deposits_count" integer NOT NULL, "withdrawals_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 INDEX "IDX_1c800426a1f738c1b202ff839f" ON "operator" ("domain_id") `)
- await db.query(`CREATE INDEX "IDX_ca18369599805e0d60e4ac0652" ON "operator" ("operator_id") `)
- await db.query(`CREATE INDEX "IDX_51b6c3609906ff3cd25e39e1b2" ON "operator" ("signing_key") `)
- await db.query(`CREATE INDEX "IDX_3b141ec6a3d1225075d8c6bc21" ON "operator" ("owner") `)
- await db.query(`CREATE INDEX "IDX_c7fd0bf382a9832cf1db87827c" ON "operator" ("status") `)
- await db.query(`CREATE INDEX "IDX_d6260ed02d20cf8231ebb742d6" ON "operator" ("created_at") `)
- await db.query(`CREATE INDEX "IDX_d6d18ca05472785030a7a3963b" ON "operator" ("updated_at") `)
- await db.query(`CREATE TABLE "domain" ("id" character varying NOT NULL, "domain_id" integer NOT NULL, "completed_epoch" integer NOT NULL, "last_domain_block_number" integer NOT NULL, "created_at" integer, "updated_at" integer, "last_operator_bundle_produced_id" character varying, CONSTRAINT "PK_27e3ec3ea0ae02c8c5bceab3ba9" PRIMARY KEY ("id"))`)
- await db.query(`CREATE INDEX "IDX_2bc5e1041a74e1492dfda20688" ON "domain" ("domain_id") `)
- await db.query(`CREATE INDEX "IDX_80867983eb3f6e204acfea4214" ON "domain" ("completed_epoch") `)
- await db.query(`CREATE INDEX "IDX_555eee0485a3e1937915a26e6b" ON "domain" ("last_operator_bundle_produced_id") `)
- await db.query(`CREATE INDEX "IDX_e3a1b94f40001682587d9b0a3d" ON "domain" ("last_domain_block_number") `)
- await db.query(`CREATE INDEX "IDX_35b49bec8ab1e3864de09a60d6" ON "domain" ("created_at") `)
- await db.query(`CREATE INDEX "IDX_c3ac554ab7a2ed97d9a0af4083" ON "domain" ("updated_at") `)
+ await db.query(`CREATE TABLE "withdrawal" ("id" character varying NOT NULL, "block_number" integer NOT NULL, "account_id" text NOT NULL, "domain_id" text NOT NULL, "operator_id" text NOT NULL, "nominator_id" text NOT NULL, "shares" numeric NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, "extrinsic_hash" text NOT NULL, "status" character varying(8) NOT NULL, CONSTRAINT "PK_840e247aaad3fbd4e18129122a2" PRIMARY KEY ("id"))`)
+ await db.query(`CREATE INDEX "IDX_e8ac24b4a9b9657cd27289feea" ON "withdrawal" ("block_number") `)
+ await db.query(`CREATE INDEX "IDX_66c152572f8743fcd9ddecf2d2" ON "withdrawal" ("account_id") `)
+ await db.query(`CREATE INDEX "IDX_12de4d5556aa377a203cb5b1b2" ON "withdrawal" ("domain_id") `)
+ await db.query(`CREATE INDEX "IDX_d5f5ce8abff91d6485c4f84e57" ON "withdrawal" ("operator_id") `)
+ await db.query(`CREATE INDEX "IDX_09c9cf2ad9a4f3b674540dbfcf" ON "withdrawal" ("nominator_id") `)
+ await db.query(`CREATE INDEX "IDX_e2749aaf8ba367458c360a7c73" ON "withdrawal" ("timestamp") `)
+ await db.query(`CREATE INDEX "IDX_9c33f1820b02bef49172b9883f" ON "withdrawal" ("extrinsic_hash") `)
+ await db.query(`CREATE INDEX "IDX_4028ed4e39f5c919fc3317882b" ON "withdrawal" ("status") `)
await db.query(`CREATE TABLE "operator_unlocked_funds" ("id" character varying NOT NULL, "block_number" integer NOT NULL, "nominator_account" text NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, "extrinsic_hash" text NOT NULL, "amount" numeric NOT NULL, "operator_id" character varying, "nominator_id" character varying, CONSTRAINT "PK_88e0c471830b6c83ae6df8e561a" PRIMARY KEY ("id"))`)
await db.query(`CREATE INDEX "IDX_c5936076e548d50542cf776289" ON "operator_unlocked_funds" ("block_number") `)
await db.query(`CREATE INDEX "IDX_8d1c61c4fa2cbdf5da095a3ffd" ON "operator_unlocked_funds" ("operator_id") `)
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 "stats" ("id" character varying NOT NULL, "block_number" integer NOT NULL, "total_domains" integer NOT NULL, "total_operators" integer NOT NULL, "total_nominators" integer NOT NULL, "total_active_operators" integer NOT NULL, "total_slashed_operators" 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, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, CONSTRAINT "PK_c76e93dfef28ba9b6942f578ab1" PRIMARY KEY ("id"))`)
+ 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 "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") `)
- await db.query(`CREATE TABLE "stats_per_domain" ("id" character varying NOT NULL, "domain_id" integer NOT NULL, "block_number" integer NOT NULL, "total_operators" integer NOT NULL, "total_nominators" integer NOT NULL, "total_active_operators" integer NOT NULL, "total_slashed_operators" 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, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, CONSTRAINT "PK_0edbe67267dbe09a2a691517eee" PRIMARY KEY ("id"))`)
+ await db.query(`CREATE TABLE "stats_per_domain" ("id" character varying NOT NULL, "domain_id" text 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, "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_0edbe67267dbe09a2a691517eee" PRIMARY KEY ("id"))`)
await db.query(`CREATE INDEX "IDX_3ac1b575a2dd3f64faedbde14b" ON "stats_per_domain" ("domain_id") `)
await db.query(`CREATE INDEX "IDX_77118ccf015e661215115daaa5" ON "stats_per_domain" ("block_number") `)
await db.query(`CREATE INDEX "IDX_8eb7279e3beeab2964a533cd52" ON "stats_per_domain" ("timestamp") `)
- await db.query(`CREATE TABLE "stats_per_operator" ("id" character varying NOT NULL, "domain_id" integer NOT NULL, "operator_id" integer NOT NULL, "block_number" integer NOT NULL, "total_nominators" 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, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, CONSTRAINT "PK_8cff6fe09e3e5510f0c90e42cf5" PRIMARY KEY ("id"))`)
+ await db.query(`CREATE TABLE "stats_per_operator" ("id" character varying NOT NULL, "domain_id" text NOT NULL, "operator_id" text 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, "nominators_count" integer NOT NULL, "deposits_count" integer NOT NULL, "withdrawals_count" integer NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, CONSTRAINT "PK_8cff6fe09e3e5510f0c90e42cf5" PRIMARY KEY ("id"))`)
await db.query(`CREATE INDEX "IDX_4a4bff6af8198a2f145ecf637f" ON "stats_per_operator" ("domain_id") `)
await db.query(`CREATE INDEX "IDX_466db26acddfccae0a5d487d2c" ON "stats_per_operator" ("operator_id") `)
await db.query(`CREATE INDEX "IDX_5ff9cc7e82a620057ef84c3826" ON "stats_per_operator" ("block_number") `)
await db.query(`CREATE INDEX "IDX_3260a5fceb17a3d817e5678d7f" ON "stats_per_operator" ("timestamp") `)
- await db.query(`ALTER TABLE "withdrawal" ADD CONSTRAINT "FK_d5f5ce8abff91d6485c4f84e574" FOREIGN KEY ("operator_id") REFERENCES "operator"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`)
- await db.query(`ALTER TABLE "withdrawal" ADD CONSTRAINT "FK_09c9cf2ad9a4f3b674540dbfcf0" FOREIGN KEY ("nominator_id") REFERENCES "nominator"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`)
- await db.query(`ALTER TABLE "nominator" ADD CONSTRAINT "FK_14374f281ccb6e72c55dab3c209" FOREIGN KEY ("operator_id") REFERENCES "operator"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`)
- await db.query(`ALTER TABLE "deposit" ADD CONSTRAINT "FK_c2f2cfaa2b294c75d38a57e380a" FOREIGN KEY ("operator_id") REFERENCES "operator"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`)
- await db.query(`ALTER TABLE "deposit" ADD CONSTRAINT "FK_b673efd4ec207b203e4d06abe9c" FOREIGN KEY ("nominator_id") REFERENCES "nominator"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`)
- await db.query(`ALTER TABLE "operator_reward_event" ADD CONSTRAINT "FK_b9cf23c6256a9fc7e01a2713761" FOREIGN KEY ("operator_id") REFERENCES "operator"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`)
- await db.query(`ALTER TABLE "operator_fees_earned" ADD CONSTRAINT "FK_c9dda7e56175bc755c449c5e02f" FOREIGN KEY ("operator_id") REFERENCES "operator"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`)
- await db.query(`ALTER TABLE "domain" ADD CONSTRAINT "FK_555eee0485a3e1937915a26e6b2" FOREIGN KEY ("last_operator_bundle_produced_id") REFERENCES "operator"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`)
await db.query(`ALTER TABLE "operator_unlocked_funds" ADD CONSTRAINT "FK_8d1c61c4fa2cbdf5da095a3ffd0" FOREIGN KEY ("operator_id") REFERENCES "operator"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`)
await db.query(`ALTER TABLE "operator_unlocked_funds" ADD CONSTRAINT "FK_2fff22e92b7b71ed2f39466e57f" FOREIGN KEY ("nominator_id") REFERENCES "nominator"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`)
}
async down(db) {
- await db.query(`DROP TABLE "withdrawal"`)
- await db.query(`DROP INDEX "public"."IDX_e8ac24b4a9b9657cd27289feea"`)
- await db.query(`DROP INDEX "public"."IDX_25c7ac5a7731ac3ce7982bef67"`)
- await db.query(`DROP INDEX "public"."IDX_d5f5ce8abff91d6485c4f84e57"`)
- await db.query(`DROP INDEX "public"."IDX_09c9cf2ad9a4f3b674540dbfcf"`)
- await db.query(`DROP INDEX "public"."IDX_e2749aaf8ba367458c360a7c73"`)
- await db.query(`DROP INDEX "public"."IDX_9c33f1820b02bef49172b9883f"`)
- await db.query(`DROP INDEX "public"."IDX_4028ed4e39f5c919fc3317882b"`)
+ await db.query(`DROP TABLE "domain"`)
+ await db.query(`DROP INDEX "public"."IDX_c1e90b3654ffe0a5544e502edb"`)
+ await db.query(`DROP INDEX "public"."IDX_80867983eb3f6e204acfea4214"`)
+ await db.query(`DROP INDEX "public"."IDX_e3a1b94f40001682587d9b0a3d"`)
+ await db.query(`DROP INDEX "public"."IDX_35b49bec8ab1e3864de09a60d6"`)
+ await db.query(`DROP INDEX "public"."IDX_c3ac554ab7a2ed97d9a0af4083"`)
+ await db.query(`DROP TABLE "account"`)
+ await db.query(`DROP INDEX "public"."IDX_2740156ea8742b8df1ad9d9774"`)
+ await db.query(`DROP INDEX "public"."IDX_8bed31488e09ed64770378600b"`)
+ await db.query(`DROP TABLE "operator"`)
+ await db.query(`DROP INDEX "public"."IDX_ed3a1bcef6df98998f07a571a7"`)
+ 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_c7fd0bf382a9832cf1db87827c"`)
+ await db.query(`DROP INDEX "public"."IDX_d6260ed02d20cf8231ebb742d6"`)
+ await db.query(`DROP INDEX "public"."IDX_d6d18ca05472785030a7a3963b"`)
await db.query(`DROP TABLE "nominator"`)
- await db.query(`DROP INDEX "public"."IDX_ef8faa81be0a51d54fc727b9fb"`)
+ await db.query(`DROP INDEX "public"."IDX_917636e6d1130ea9506eaeafef"`)
+ await db.query(`DROP INDEX "public"."IDX_b017cafe03fa79059bd8164c4e"`)
await db.query(`DROP INDEX "public"."IDX_14374f281ccb6e72c55dab3c20"`)
await db.query(`DROP INDEX "public"."IDX_43aeeb4c46d83dd78aa564c1b1"`)
await db.query(`DROP INDEX "public"."IDX_7093d62ba7e5a6387a686e607e"`)
await db.query(`DROP INDEX "public"."IDX_9ebc942736e76bde99ee21452f"`)
await db.query(`DROP TABLE "deposit"`)
await db.query(`DROP INDEX "public"."IDX_230a90fc5a10c7ac5ac35397d2"`)
- await db.query(`DROP INDEX "public"."IDX_f3abde1e7f8d7ca5102e376219"`)
+ await db.query(`DROP INDEX "public"."IDX_9ced91570695137ec1d60c1a61"`)
+ await db.query(`DROP INDEX "public"."IDX_8dc544cfa89fb544beea034396"`)
await db.query(`DROP INDEX "public"."IDX_c2f2cfaa2b294c75d38a57e380"`)
await db.query(`DROP INDEX "public"."IDX_b673efd4ec207b203e4d06abe9"`)
await db.query(`DROP INDEX "public"."IDX_a37222607a86476fa124313c51"`)
await db.query(`DROP INDEX "public"."IDX_b1d1dadac59ff00a27b4ef18cf"`)
await db.query(`DROP INDEX "public"."IDX_6f250bd43f2f631fcb2f589200"`)
- await db.query(`DROP TABLE "operator_reward_event"`)
- 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 "operator_fees_earned"`)
- await db.query(`DROP INDEX "public"."IDX_c9dda7e56175bc755c449c5e02"`)
- await db.query(`DROP TABLE "operator"`)
- await db.query(`DROP INDEX "public"."IDX_1c800426a1f738c1b202ff839f"`)
- await db.query(`DROP INDEX "public"."IDX_ca18369599805e0d60e4ac0652"`)
- await db.query(`DROP INDEX "public"."IDX_51b6c3609906ff3cd25e39e1b2"`)
- await db.query(`DROP INDEX "public"."IDX_3b141ec6a3d1225075d8c6bc21"`)
- await db.query(`DROP INDEX "public"."IDX_c7fd0bf382a9832cf1db87827c"`)
- await db.query(`DROP INDEX "public"."IDX_d6260ed02d20cf8231ebb742d6"`)
- await db.query(`DROP INDEX "public"."IDX_d6d18ca05472785030a7a3963b"`)
- await db.query(`DROP TABLE "domain"`)
- await db.query(`DROP INDEX "public"."IDX_2bc5e1041a74e1492dfda20688"`)
- await db.query(`DROP INDEX "public"."IDX_80867983eb3f6e204acfea4214"`)
- await db.query(`DROP INDEX "public"."IDX_555eee0485a3e1937915a26e6b"`)
- await db.query(`DROP INDEX "public"."IDX_e3a1b94f40001682587d9b0a3d"`)
- await db.query(`DROP INDEX "public"."IDX_35b49bec8ab1e3864de09a60d6"`)
- await db.query(`DROP INDEX "public"."IDX_c3ac554ab7a2ed97d9a0af4083"`)
+ await db.query(`DROP TABLE "withdrawal"`)
+ await db.query(`DROP INDEX "public"."IDX_e8ac24b4a9b9657cd27289feea"`)
+ await db.query(`DROP INDEX "public"."IDX_66c152572f8743fcd9ddecf2d2"`)
+ await db.query(`DROP INDEX "public"."IDX_12de4d5556aa377a203cb5b1b2"`)
+ await db.query(`DROP INDEX "public"."IDX_d5f5ce8abff91d6485c4f84e57"`)
+ await db.query(`DROP INDEX "public"."IDX_09c9cf2ad9a4f3b674540dbfcf"`)
+ await db.query(`DROP INDEX "public"."IDX_e2749aaf8ba367458c360a7c73"`)
+ await db.query(`DROP INDEX "public"."IDX_9c33f1820b02bef49172b9883f"`)
+ await db.query(`DROP INDEX "public"."IDX_4028ed4e39f5c919fc3317882b"`)
await db.query(`DROP TABLE "operator_unlocked_funds"`)
await db.query(`DROP INDEX "public"."IDX_c5936076e548d50542cf776289"`)
await db.query(`DROP INDEX "public"."IDX_8d1c61c4fa2cbdf5da095a3ffd"`)
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 "stats"`)
await db.query(`DROP INDEX "public"."IDX_0b3890ae3ba62ee77fe94af26e"`)
await db.query(`DROP INDEX "public"."IDX_ea4b2bcf5920a1b06f4454bb91"`)
@@ -139,14 +139,6 @@ module.exports = class Data1721778314620 {
await db.query(`DROP INDEX "public"."IDX_466db26acddfccae0a5d487d2c"`)
await db.query(`DROP INDEX "public"."IDX_5ff9cc7e82a620057ef84c3826"`)
await db.query(`DROP INDEX "public"."IDX_3260a5fceb17a3d817e5678d7f"`)
- await db.query(`ALTER TABLE "withdrawal" DROP CONSTRAINT "FK_d5f5ce8abff91d6485c4f84e574"`)
- await db.query(`ALTER TABLE "withdrawal" DROP CONSTRAINT "FK_09c9cf2ad9a4f3b674540dbfcf0"`)
- await db.query(`ALTER TABLE "nominator" DROP CONSTRAINT "FK_14374f281ccb6e72c55dab3c209"`)
- await db.query(`ALTER TABLE "deposit" DROP CONSTRAINT "FK_c2f2cfaa2b294c75d38a57e380a"`)
- await db.query(`ALTER TABLE "deposit" DROP CONSTRAINT "FK_b673efd4ec207b203e4d06abe9c"`)
- await db.query(`ALTER TABLE "operator_reward_event" DROP CONSTRAINT "FK_b9cf23c6256a9fc7e01a2713761"`)
- await db.query(`ALTER TABLE "operator_fees_earned" DROP CONSTRAINT "FK_c9dda7e56175bc755c449c5e02f"`)
- await db.query(`ALTER TABLE "domain" DROP CONSTRAINT "FK_555eee0485a3e1937915a26e6b2"`)
await db.query(`ALTER TABLE "operator_unlocked_funds" DROP CONSTRAINT "FK_8d1c61c4fa2cbdf5da095a3ffd0"`)
await db.query(`ALTER TABLE "operator_unlocked_funds" DROP CONSTRAINT "FK_2fff22e92b7b71ed2f39466e57f"`)
}
diff --git a/indexers/staking-squid/package-lock.json b/indexers/staking-squid/package-lock.json
index 8bdc0cd87..cdddb7680 100644
--- a/indexers/staking-squid/package-lock.json
+++ b/indexers/staking-squid/package-lock.json
@@ -6,8 +6,8 @@
"": {
"name": "staking-squid",
"dependencies": {
- "@autonomys/auto-consensus": "^0.1.6",
- "@autonomys/auto-utils": "^0.1.6",
+ "@autonomys/auto-consensus": "^0.2.0",
+ "@autonomys/auto-utils": "^0.2.0",
"@subsquid/graphql-server": "^4.5.1",
"@subsquid/ss58": "^2.0.2",
"@subsquid/substrate-processor": "^8.3.0",
@@ -182,17 +182,17 @@
}
},
"node_modules/@autonomys/auto-consensus": {
- "version": "0.1.6",
- "resolved": "https://registry.npmjs.org/@autonomys/auto-consensus/-/auto-consensus-0.1.6.tgz",
- "integrity": "sha512-V65b3Vl6QBPyuqIITINZH42ebMOO9Y+Gg74EPIJxDQcaGslMBmbA2IFuKOdKJRXwfO6WQkxAIioCdMmpa6z6PA==",
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/@autonomys/auto-consensus/-/auto-consensus-0.2.0.tgz",
+ "integrity": "sha512-2kfHOVOXgdhoMAcRP46J4Tk3qeuT/CHetJNtjcVPY0H3ojGPpmfaFg2jBenQqGz59TacjSjLhSouA5UlY7iDJg==",
"dependencies": {
- "@autonomys/auto-utils": "^0.1.6"
+ "@autonomys/auto-utils": "^0.2.0"
}
},
"node_modules/@autonomys/auto-utils": {
- "version": "0.1.6",
- "resolved": "https://registry.npmjs.org/@autonomys/auto-utils/-/auto-utils-0.1.6.tgz",
- "integrity": "sha512-fCU6kjlzYsMuFx9l32GkwmzHRmUlQS2YIBbKDDohNQyixtCc7UEJSftgIhHlpXilTeZSetvVFingg/vbyChRJQ==",
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/@autonomys/auto-utils/-/auto-utils-0.2.0.tgz",
+ "integrity": "sha512-uu4OxTWXGQk09HxmQsJQTmrcKAqwdTdGQy/zUloVm5/IAYPKmI1ttSPI/5BSUxeoKsBd69XFfb3wqtYfO5/ytw==",
"dependencies": {
"@polkadot/api": "^11.2.1",
"@polkadot/extension-dapp": "^0.47.5",
@@ -1586,9 +1586,9 @@
"optional": true
},
"node_modules/@substrate/connect-known-chains": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/@substrate/connect-known-chains/-/connect-known-chains-1.1.11.tgz",
- "integrity": "sha512-jl6RKTn9bDezKqlOj2X9B/BVftIqqnU9tgr/9WXMCBdLedzQaO/DRRb0c5VqF1+DH8dHV2q5MyKN9gR+KGt7ow==",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@substrate/connect-known-chains/-/connect-known-chains-1.2.0.tgz",
+ "integrity": "sha512-BgcTHKteSAcEQs5ySNTYOO6ODQHVHwPgDrjYQhL0r8ZygY4cyXa5e2O//3tXNJiDopFHdqO8FBAy2Gbht0i0PA==",
"optional": true
},
"node_modules/@substrate/light-client-extension-helpers": {
@@ -3785,9 +3785,9 @@
}
},
"node_modules/nock/node_modules/debug": {
- "version": "4.3.5",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz",
- "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==",
+ "version": "4.3.6",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz",
+ "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==",
"dependencies": {
"ms": "2.1.2"
},
diff --git a/indexers/staking-squid/package.json b/indexers/staking-squid/package.json
index 6b4288298..d5f58b42c 100644
--- a/indexers/staking-squid/package.json
+++ b/indexers/staking-squid/package.json
@@ -5,7 +5,8 @@
"node": ">=16"
},
"scripts": {
- "build": "rm -rf lib && tsc"
+ "build": "rm -rf lib && tsc",
+ "deploy": "sqd deploy --org autonomys-labs ."
},
"repository": {
"type": "git",
@@ -13,11 +14,11 @@
},
"author": {
"name": "Autonomys",
- "url": "https://www.autonomys.net"
+ "url": "https://www.autonomys.xyz"
},
"dependencies": {
- "@autonomys/auto-consensus": "^0.1.6",
- "@autonomys/auto-utils": "^0.1.6",
+ "@autonomys/auto-consensus": "^0.2.0",
+ "@autonomys/auto-utils": "^0.2.0",
"@subsquid/graphql-server": "^4.5.1",
"@subsquid/ss58": "^2.0.2",
"@subsquid/substrate-processor": "^8.3.0",
diff --git a/indexers/staking-squid/schema.graphql b/indexers/staking-squid/schema.graphql
index 62f248e30..3600d8cc8 100644
--- a/indexers/staking-squid/schema.graphql
+++ b/indexers/staking-squid/schema.graphql
@@ -1,9 +1,21 @@
type Domain @entity {
id: ID! @index
- domainId: Int! @index
+ sortId: Int! @index
completedEpoch: Int! @index
- lastOperatorBundleProduced: Operator!
lastDomainBlockNumber: Int! @index
+ totalDeposits: BigInt!
+ totalTaxCollected: BigInt!
+ totalRewardsCollected: BigInt!
+ currentTotalStake: BigInt!
+ currentStorageFeeDeposit: BigInt!
+ createdAt: Int @index
+ updatedAt: Int @index
+}
+
+type Account @entity {
+ id: ID! @index
+ totalDeposits: BigInt!
+ totalTaxCollected: BigInt!
createdAt: Int @index
updatedAt: Int @index
}
@@ -12,15 +24,16 @@ enum OperatorStatus {
PENDING
REGISTERED
DEREGISTERED
+ READY_TO_UNLOCK
SLASHED
}
type Operator @entity {
id: ID! @index
- domainId: Int! @index
- operatorId: Int! @index
+ sortId: Int! @index
+ accountId: String! @index
+ domainId: String! @index
signingKey: String! @index
- owner: String! @index
minimumNominatorStake: BigInt!
nominationTax: Int!
currentTotalStake: BigInt!
@@ -29,26 +42,9 @@ type Operator @entity {
currentTotalShares: BigInt!
totalDeposits: BigInt!
totalTaxCollected: BigInt!
- deposits: [Deposit!]!
- @derivedFrom(field: "operator")
- @cardinality(value: 1000000000)
- nominators: [Nominator!]!
- @derivedFrom(field: "operator")
- @cardinality(value: 1000000000)
- withdrawals: [Withdrawal!]!
- @derivedFrom(field: "operator")
- @cardinality(value: 1000000000)
- operatorRewards: [OperatorRewardEvent!]!
- @derivedFrom(field: "operator")
- @cardinality(value: 1000000000)
- operatorFees: [OperatorFeesEarned!]!
- @derivedFrom(field: "operator")
- @cardinality(value: 1000000000)
+ totalRewardsCollected: BigInt!
rawStatus: String
status: OperatorStatus! @index
- nominatorsCount: Int!
- depositsCount: Int!
- withdrawalsCount: Int!
bundleCount: Int!
lastBundleAt: Int!
createdAt: Int @index
@@ -64,18 +60,11 @@ enum NominatorStatus {
type Nominator @entity {
id: ID! @index
- account: String! @index
- operator: Operator!
+ accountId: String! @index
+ domainId: String! @index
+ operatorId: String! @index
shares: BigInt!
- deposits: [Deposit!]!
- @derivedFrom(field: "nominator")
- @cardinality(value: 1000000000)
- withdrawals: [Withdrawal!]!
- @derivedFrom(field: "nominator")
- @cardinality(value: 1000000000)
totalDeposits: BigInt!
- depositsCount: Int!
- withdrawalsCount: Int!
status: NominatorStatus! @index
createdAt: Int @index
updatedAt: Int @index
@@ -89,11 +78,12 @@ enum DepositStatus {
type Deposit @entity {
id: ID! @index
blockNumber: Int! @index
- account: String! @index
+ accountId: String! @index
+ domainId: String! @index
+ operatorId: String! @index
+ nominatorId: String! @index
amount: BigInt!
storageFeeDeposit: BigInt!
- operator: Operator!
- nominator: Nominator!
timestamp: DateTime! @index
extrinsicHash: String! @index
status: DepositStatus! @index
@@ -108,10 +98,11 @@ enum WithdrawalStatus {
type Withdrawal @entity {
id: ID! @index
blockNumber: Int! @index
- account: String! @index
+ accountId: String! @index
+ domainId: String! @index
+ operatorId: String! @index
+ nominatorId: String! @index
shares: BigInt!
- operator: Operator!
- nominator: Nominator!
timestamp: DateTime! @index
extrinsicHash: String! @index
status: WithdrawalStatus! @index
@@ -130,62 +121,62 @@ type OperatorUnlockedFunds @entity {
type OperatorRewardEvent @entity {
id: ID! @index
- operator: Operator!
+ domainId: String! @index
+ operatorId: String! @index
+ amount: BigInt!
timestamp: DateTime! @index
blockNumber: Int! @index
extrinsicHash: String! @index
- amount: BigInt!
-}
-
-type OperatorFeesEarned @entity {
- id: ID! @index
- operator: Operator!
- amount: BigInt!
- updatedAt: Int!
}
type Stats @entity {
id: ID! @index
blockNumber: Int! @index
- totalDomains: Int!
- totalOperators: Int!
- totalNominators: Int!
- totalActiveOperators: Int!
- totalSlashedOperators: Int!
totalStaked: BigInt!
totalFees: BigInt!
totalDeposits: BigInt!
totalWithdrawals: BigInt!
allTimeHighStaked: BigInt!
+ domainsCount: Int!
+ operatorsCount: Int!
+ activeOperatorsCount: Int!
+ slashedOperatorsCount: Int!
+ nominatorsCount: Int!
+ depositsCount: Int!
+ withdrawalsCount: Int!
timestamp: DateTime! @index
}
type StatsPerDomain @entity {
id: ID! @index
- domainId: Int! @index
+ domainId: String! @index
blockNumber: Int! @index
- totalOperators: Int!
- totalNominators: Int!
- totalActiveOperators: Int!
- totalSlashedOperators: Int!
totalStaked: BigInt!
totalFees: BigInt!
totalDeposits: BigInt!
totalWithdrawals: BigInt!
allTimeHighStaked: BigInt!
+ operatorsCount: Int!
+ activeOperatorsCount: Int!
+ slashedOperatorsCount: Int!
+ nominatorsCount: Int!
+ depositsCount: Int!
+ withdrawalsCount: Int!
timestamp: DateTime! @index
}
type StatsPerOperator @entity {
id: ID! @index
- domainId: Int! @index
- operatorId: Int! @index
+ domainId: String! @index
+ operatorId: String! @index
blockNumber: Int! @index
- totalNominators: Int!
totalStaked: BigInt!
totalFees: BigInt!
totalDeposits: BigInt!
totalWithdrawals: BigInt!
allTimeHighStaked: BigInt!
+ nominatorsCount: Int!
+ depositsCount: Int!
+ withdrawalsCount: Int!
timestamp: DateTime! @index
}
diff --git a/indexers/staking-squid/squid.yaml b/indexers/staking-squid/squid.yaml
index 582060d4b..05d778221 100644
--- a/indexers/staking-squid/squid.yaml
+++ b/indexers/staking-squid/squid.yaml
@@ -1,11 +1,16 @@
manifestVersion: subsquid.io/v0.1
name: staking-squid
-version: 1
+version: 2
description: Autonomys - Astral - Staking Indexer
build:
deploy:
+ env:
+ HASURA_GRAPHQL_ADMIN_SECRET: "${{ secrets.HASURA_SECRET }}"
+ HASURA_GRAPHQL_UNAUTHORIZED_ROLE: user
+ HASURA_GRAPHQL_STRINGIFY_NUMERIC_TYPES: "true"
addons:
postgres:
+ hasura:
processor:
cmd:
- sqd
@@ -17,3 +22,12 @@ deploy:
cmd:
- sqd
- serve:prod
+
+scale:
+ dedicated: true
+ addons:
+ postgres:
+ storage: 100G
+ profile: medium
+ processor:
+ profile: medium
diff --git a/indexers/staking-squid/src/blocks/index.ts b/indexers/staking-squid/src/blocks/index.ts
index 0771b2e8c..905ae6c1b 100644
--- a/indexers/staking-squid/src/blocks/index.ts
+++ b/indexers/staking-squid/src/blocks/index.ts
@@ -1,22 +1,22 @@
import type { ApiPromise } from "@autonomys/auto-utils";
-import type { ApiDecoration } from "@polkadot/api/types";
-import type { Store } from "@subsquid/typeorm-store";
+import { Store } from "@subsquid/typeorm-store";
import { processExtrinsics } from "../extrinsics";
import type { Ctx, CtxBlock } from "../processor";
import { getBlockNumber } from "../utils";
+import { Cache, load, save } from "../utils/cache";
export async function processBlocks(ctx: Ctx, api: ApiPromise) {
+ let cache: Cache = await load(ctx);
+ console.log("Processing " + ctx.blocks.length + " blocks");
for (let block of ctx.blocks) {
- const apiAt = await api.at(block.header.hash);
- await processBlock(ctx, apiAt, block);
+ cache = await processBlock(cache, api, block);
+
+ ctx.log.child("completed block").info(getBlockNumber(block).toString());
+
+ await save(ctx, cache);
}
}
-async function processBlock(
- ctx: Ctx,
- apiAt: ApiDecoration<"promise">,
- block: CtxBlock
-) {
- await processExtrinsics(ctx, apiAt, block, block.extrinsics);
- ctx.log.child(`Last block`).info(getBlockNumber(block).toString());
+async function processBlock(cache: Cache, api: ApiPromise, block: CtxBlock) {
+ return await processExtrinsics(cache, api, block, block.extrinsics);
}
diff --git a/indexers/staking-squid/src/events/bundle.ts b/indexers/staking-squid/src/events/bundle.ts
index 8d2731c97..1b9877c00 100644
--- a/indexers/staking-squid/src/events/bundle.ts
+++ b/indexers/staking-squid/src/events/bundle.ts
@@ -1,12 +1,10 @@
-import type { ApiDecoration } from "@polkadot/api/types";
-import type { Store } from "@subsquid/typeorm-store";
-import type { Ctx, CtxBlock, CtxEvent, CtxExtrinsic } from "../processor";
+import type { CtxBlock, CtxEvent, CtxExtrinsic } from "../processor";
import { getOrCreateDomain, getOrCreateOperator } from "../storage";
import { getBlockNumber } from "../utils";
+import { Cache } from "../utils/cache";
-export async function processBundleStoredEvent(
- ctx: Ctx,
- apiAt: ApiDecoration<"promise">,
+export function processBundleStoredEvent(
+ cache: Cache,
block: CtxBlock,
extrinsic: CtxExtrinsic,
event: CtxEvent
@@ -14,21 +12,22 @@ export async function processBundleStoredEvent(
const domainId = Number(event.args.domainId);
const operatorId = Number(event.args.bundleAuthor);
const lastDomainBlockNumber = Number(
- extrinsic.call?.args[0].value.sealed_header.header.receipt
- .domain_block_number
+ extrinsic.call?.args.opaqueBundle.sealedHeader.header.receipt
+ .domainBlockNumber
);
- const domain = await getOrCreateDomain(ctx, block, domainId);
- const operator = await getOrCreateOperator(ctx, block, operatorId);
+ const domain = getOrCreateDomain(cache, block, domainId);
+ const operator = getOrCreateOperator(cache, block, operatorId);
- domain.lastOperatorBundleProduced = operator;
domain.lastDomainBlockNumber = lastDomainBlockNumber;
domain.updatedAt = getBlockNumber(block);
- await ctx.store.save(domain);
+ cache.domains.set(domain.id, domain);
operator.bundleCount++;
operator.lastBundleAt = getBlockNumber(block);
operator.updatedAt = getBlockNumber(block);
- await ctx.store.save(operator);
+ cache.operators.set(operator.id, operator);
+
+ return cache;
}
diff --git a/indexers/staking-squid/src/events/domain.ts b/indexers/staking-squid/src/events/domain.ts
index 8e572ba02..f0dcfd4fc 100644
--- a/indexers/staking-squid/src/events/domain.ts
+++ b/indexers/staking-squid/src/events/domain.ts
@@ -1,17 +1,18 @@
-import type { ApiDecoration } from "@polkadot/api/types";
-import type { Store } from "@subsquid/typeorm-store";
-import type { Ctx, CtxBlock, CtxEvent, CtxExtrinsic } from "../processor";
-import { createDomain } from "../storage";
+import type { CtxBlock, CtxEvent } from "../processor";
+import { getOrCreateDomain } from "../storage";
+import { Cache } from "../utils/cache";
-export async function processDomainInstantiatedEvent(
- ctx: Ctx,
- apiAt: ApiDecoration<"promise">,
+export function processDomainInstantiatedEvent(
+ cache: Cache,
block: CtxBlock,
- extrinsic: CtxExtrinsic,
event: CtxEvent
) {
- await createDomain(ctx, block, {
- domainId: Number(event.args.domainId || 0),
+ const domainId = Number(event.args.domainId || 0);
+ const domain = getOrCreateDomain(cache, block, domainId, {
completedEpoch: Number(event.args.completedEpochIndex || 0),
});
+
+ cache.domains.set(domain.id, domain);
+
+ return cache;
}
diff --git a/indexers/staking-squid/src/events/epoch.ts b/indexers/staking-squid/src/events/epoch.ts
index d26d019a2..0e2866ec5 100644
--- a/indexers/staking-squid/src/events/epoch.ts
+++ b/indexers/staking-squid/src/events/epoch.ts
@@ -1,58 +1,130 @@
-import { parseOperator } from "@autonomys/auto-consensus";
-import type { ApiDecoration } from "@polkadot/api/types";
-import type { Store } from "@subsquid/typeorm-store";
-import type { Ctx, CtxBlock, CtxEvent, CtxExtrinsic } from "../processor";
+import { operators as getOperators } from "@autonomys/auto-consensus";
+import type { ApiPromise } from "@autonomys/auto-utils";
+import { DepositStatus, NominatorStatus, OperatorStatus } from "../model";
+import type { CtxBlock, CtxEvent, CtxExtrinsic } from "../processor";
import {
- createDomain,
+ createStats,
+ createStatsPerDomain,
+ createStatsPerOperator,
getOrCreateDomain,
getOrCreateOperator,
} from "../storage";
import { getBlockNumber } from "../utils";
+import { Cache } from "../utils/cache";
export async function processEpochTransitionEvent(
- ctx: Ctx,
- apiAt: ApiDecoration<"promise">,
+ cache: Cache,
+ api: ApiPromise,
block: CtxBlock,
extrinsic: CtxExtrinsic,
event: CtxEvent
) {
const domainId = Number(event.args.domainId);
- const domain = await getOrCreateDomain(ctx, block, domainId);
+ const domain = getOrCreateDomain(cache, block, domainId);
const completedEpoch = Number(event.args.completedEpochIndex);
- if (!domain)
- await createDomain(ctx, block, {
- domainId,
- completedEpoch: Number(event.args.completedEpochIndex),
- });
- else {
- domain.completedEpoch = Number(event.args.completedEpochIndex);
- domain.updatedAt = getBlockNumber(block);
-
- await ctx.store.save(domain);
- }
+ const apiAt = await api.at(block.header.hash);
- const operatorsAll = await apiAt.query.domains.operators.entries();
- const allOperators = (operatorsAll as unknown as any[]).map((o) =>
- parseOperator(o)
+ const operatorsAll = await getOperators(apiAt);
+ const allOperators = operatorsAll.filter(
+ (o) => o.operatorDetails.currentDomainId === BigInt(domainId)
);
+
for (const operator of allOperators) {
- const op = await getOrCreateOperator(
- ctx,
+ const op = getOrCreateOperator(
+ cache,
block,
parseInt(operator.operatorId.toString())
);
+
+ const rawStatus = JSON.stringify(operator.operatorDetails.status);
op.currentEpochRewards = operator.operatorDetails.currentEpochRewards;
op.currentTotalShares = operator.operatorDetails.currentTotalShares;
op.currentTotalStake = operator.operatorDetails.currentTotalStake;
op.currentStorageFeeDeposit =
operator.operatorDetails.totalStorageFeeDeposit;
- op.rawStatus = JSON.stringify(operator.operatorDetails.status);
+ op.rawStatus = rawStatus;
op.updatedAt = getBlockNumber(block);
- await ctx.store.save(op);
+ cache.operators.set(op.id, op);
+
+ try {
+ const rawStatusKey = Object.keys(rawStatus);
+ if (rawStatusKey[0] === "deregistered") {
+ const unlockBlock = (
+ rawStatus as unknown as {
+ deregistered: { unlockAtConfirmedDomainBlockNumber: number };
+ }
+ ).deregistered.unlockAtConfirmedDomainBlockNumber;
+
+ if (unlockBlock <= domain.lastDomainBlockNumber) {
+ op.status = OperatorStatus.READY_TO_UNLOCK;
+ cache.operators.set(op.id, op);
+ }
+ }
+ } catch (e) {
+ console.error("Error in processEpochTransitionEvent", e);
+ }
+ }
+
+ domain.currentTotalStake = allOperators.reduce(
+ (acc, o) => acc + o.operatorDetails.currentTotalStake,
+ BigInt(0)
+ );
+ domain.currentStorageFeeDeposit = allOperators.reduce(
+ (acc, o) => acc + o.operatorDetails.totalStorageFeeDeposit,
+ BigInt(0)
+ );
+
+ domain.completedEpoch = completedEpoch;
+ domain.updatedAt = getBlockNumber(block);
+
+ cache.domains.set(domain.id, domain);
+
+ // Switch Pending to Active
+ Array.from(cache.operators.values())
+ .filter((o) => o.status === OperatorStatus.PENDING)
+ .map((o) => {
+ o.status = OperatorStatus.REGISTERED;
+ o.updatedAt = getBlockNumber(block);
+ cache.operators.set(o.id, o);
+ });
+ Array.from(cache.nominators.values())
+ .filter((n) => n.status === NominatorStatus.PENDING)
+ .map((n) => {
+ n.status = NominatorStatus.STAKING;
+ n.updatedAt = getBlockNumber(block);
+ cache.nominators.set(n.id, n);
+ });
+ Array.from(cache.deposits.values())
+ .filter((d) => d.status === DepositStatus.PENDING)
+ .map((d) => {
+ d.status = DepositStatus.DEPOSITED;
+ cache.deposits.set(d.id, d);
+ });
+
+ // Stats on epoch transition
+ const stats = createStats(cache, block);
+ cache.stats.set(stats.id, stats);
+
+ const domains = Array.from(cache.domains.values());
+ for (const domain of domains) {
+ const statsPerDomain = createStatsPerDomain(cache, block, domain);
+ cache.statsPerDomain.set(statsPerDomain.id, statsPerDomain);
+
+ const operators = Array.from(cache.operators.values()).filter(
+ (o) => o.domainId === domain.id
+ );
+ for (const operator of operators) {
+ const statsPerOperator = createStatsPerOperator(
+ cache,
+ block,
+ domain,
+ operator
+ );
+ cache.statsPerOperator.set(statsPerOperator.id, statsPerOperator);
+ }
}
- ctx.log
- .child(`DomainId ${domainId} - Current epoch`)
- .info(completedEpoch.toString());
+
+ return cache;
}
diff --git a/indexers/staking-squid/src/events/index.ts b/indexers/staking-squid/src/events/index.ts
index ed498040b..3ab496c75 100644
--- a/indexers/staking-squid/src/events/index.ts
+++ b/indexers/staking-squid/src/events/index.ts
@@ -1,51 +1,49 @@
-import type { ApiDecoration } from "@polkadot/api/types";
-import type { Store } from "@subsquid/typeorm-store";
-import type { ProcessorContext } from "../processor";
+import type { ApiPromise } from "@autonomys/auto-utils";
+import type { CtxBlock, CtxEvent, CtxExtrinsic } from "../processor";
import { events } from "../types";
+import { Cache } from "../utils/cache";
import { processBundleStoredEvent } from "./bundle";
import { processDomainInstantiatedEvent } from "./domain";
import { processEpochTransitionEvent } from "./epoch";
import {
processOperatorNominatedEvent,
+ processOperatorRewardedEvent,
processOperatorSlashedEvent,
processOperatorTaxCollectedEvent,
} from "./operator";
+import { processWithdrewStakeEvent } from "./withdraw";
export async function processEvents(
- ctx: ProcessorContext,
- apiAt: ApiDecoration<"promise">,
- block: ProcessorContext["blocks"][0],
- extrinsic: ProcessorContext["blocks"][0]["extrinsics"][0]
+ cache: Cache,
+ api: ApiPromise,
+ block: CtxBlock,
+ extrinsic: CtxExtrinsic
) {
for (let event of extrinsic.events) {
- await processEvent(ctx, apiAt, block, extrinsic, event);
+ cache = await processEvent(cache, api, block, extrinsic, event);
}
+ return cache;
}
async function processEvent(
- ctx: ProcessorContext,
- apiAt: ApiDecoration<"promise">,
- block: ProcessorContext["blocks"][0],
- extrinsic: ProcessorContext["blocks"][0]["extrinsics"][0],
- event: ProcessorContext["blocks"][0]["extrinsics"][0]["events"][0]
+ cache: Cache,
+ api: ApiPromise,
+ block: CtxBlock,
+ extrinsic: CtxExtrinsic,
+ event: CtxEvent
) {
+ console.log("event", event.name);
switch (event.name) {
// new domain
case events.domains.domainInstantiated.name:
- return await processDomainInstantiatedEvent(
- ctx,
- apiAt,
- block,
- extrinsic,
- event
- );
+ return processDomainInstantiatedEvent(cache, block, event);
// epoch transition
case events.domains.domainEpochCompleted.name:
case events.domains.forceDomainEpochTransition.name:
return await processEpochTransitionEvent(
- ctx,
- apiAt,
+ cache,
+ api,
block,
extrinsic,
event
@@ -53,48 +51,28 @@ async function processEvent(
// operator and nomination
case events.domains.operatorNominated.name:
- return await processOperatorNominatedEvent(
- ctx,
- apiAt,
- block,
- extrinsic,
- event
- );
+ return processOperatorNominatedEvent(cache, block, extrinsic, event);
// bundle
case events.domains.bundleStored.name:
- return await processBundleStoredEvent(
- ctx,
- apiAt,
- block,
- extrinsic,
- event
- );
+ return processBundleStoredEvent(cache, block, extrinsic, event);
+
+ // deposit and stake
+ case events.domains.withdrewStake.name:
+ return processWithdrewStakeEvent(cache, block, extrinsic, event);
// rewards and slashing
case events.domains.operatorRewarded.name:
- break;
+ return processOperatorRewardedEvent(cache, block, extrinsic, event);
case events.domains.operatorSlashed.name:
- return await processOperatorSlashedEvent(
- ctx,
- apiAt,
- block,
- extrinsic,
- event
- );
+ return processOperatorSlashedEvent(cache, block, extrinsic, event);
// tax on fees
case events.domains.operatorTaxCollected.name:
- return await processOperatorTaxCollectedEvent(
- ctx,
- apiAt,
- block,
- extrinsic,
- event
- );
+ return processOperatorTaxCollectedEvent(cache, block, extrinsic, event);
default:
- break;
+ return cache;
}
}
diff --git a/indexers/staking-squid/src/events/operator.ts b/indexers/staking-squid/src/events/operator.ts
index f6f7dd389..3e7c02868 100644
--- a/indexers/staking-squid/src/events/operator.ts
+++ b/indexers/staking-squid/src/events/operator.ts
@@ -1,31 +1,31 @@
-import type { ApiDecoration } from "@polkadot/api/types";
-import type { Store } from "@subsquid/typeorm-store";
-import { Nominator, NominatorStatus, OperatorStatus } from "../model";
-import type { Ctx, CtxBlock, CtxEvent, CtxExtrinsic } from "../processor";
+import { DepositStatus, NominatorStatus, OperatorStatus } from "../model";
+import type { CtxBlock, CtxEvent, CtxExtrinsic } from "../processor";
import {
- getOrCreateDeposit,
+ createDeposit,
+ createOperatorRewardEvent,
+ getOrCreateAccount,
+ getOrCreateDomain,
getOrCreateNominator,
getOrCreateOperator,
} from "../storage";
import { events } from "../types";
-import { appendOrArray, getBlockNumber } from "../utils";
+import { getBlockNumber, getCallSigner } from "../utils";
+import { Cache } from "../utils/cache";
-export async function processOperatorNominatedEvent(
- ctx: Ctx,
- apiAt: ApiDecoration<"promise">,
+export function processOperatorNominatedEvent(
+ cache: Cache,
block: CtxBlock,
extrinsic: CtxExtrinsic,
event: CtxEvent
) {
+ const address = getCallSigner(extrinsic.call);
+ const blockNumber = getBlockNumber(block);
const operatorId = Number(event.args.operatorId);
const storageFeeDepositedEvent = extrinsic.events.find(
(e) => e.name === events.domains.storageFeeDeposited.name
);
- const shares = extrinsic.call
- ? BigInt(extrinsic.call.args.shares)
- : BigInt(0);
const amount = extrinsic.call
? BigInt(extrinsic.call.args.amount)
: BigInt(0);
@@ -33,85 +33,147 @@ export async function processOperatorNominatedEvent(
? BigInt(storageFeeDepositedEvent.args.amount)
: BigInt(0);
- const operator = await getOrCreateOperator(ctx, block, operatorId);
- const nominator = await getOrCreateNominator(
- ctx,
- block,
- extrinsic,
- operator,
- {
- shares,
- }
- );
- const deposit = await getOrCreateDeposit(ctx, block, extrinsic, operator, {
+ const account = getOrCreateAccount(cache, block, address);
+ cache.accounts.set(account.id, account);
+
+ const operator = getOrCreateOperator(cache, block, operatorId, {});
+ cache.operators.set(operator.id, operator);
+
+ const domain = getOrCreateDomain(cache, block, operator.domainId);
+ cache.domains.set(domain.id, domain);
+
+ const nominator = getOrCreateNominator(cache, block, extrinsic, operatorId, {
+ domainId: domain.id,
+ accountId: account.id,
+ operatorId: operator.id,
+ });
+ cache.nominators.set(nominator.id, nominator);
+
+ const deposit = createDeposit(block, extrinsic, {
+ domainId: domain.id,
+ accountId: account.id,
+ operatorId: operator.id,
+ nominatorId: nominator.id,
amount,
storageFeeDeposit,
});
+ cache.deposits.set(deposit.id, deposit);
- operator.totalDeposits += deposit.amount;
+ operator.totalDeposits += amount;
+ operator.updatedAt = blockNumber;
- const operatorNominators = appendOrArray(operator.nominators, nominator);
- operator.nominators = operatorNominators;
- operator.nominatorsCount = operatorNominators.length;
+ cache.operators.set(operator.id, operator);
- const operatorDeposits = appendOrArray(operator.deposits, deposit);
- operator.deposits = operatorDeposits;
- operator.depositsCount = operatorDeposits.length;
+ nominator.totalDeposits += amount;
+ nominator.updatedAt = blockNumber;
- operator.updatedAt = getBlockNumber(block);
+ cache.nominators.set(nominator.id, nominator);
- await ctx.store.save(operator);
+ domain.totalDeposits += amount;
+ domain.updatedAt = blockNumber;
- nominator.totalDeposits += deposit.amount;
+ cache.domains.set(domain.id, domain);
- const nominatorDeposits = appendOrArray(nominator.deposits, deposit);
- nominator.deposits = nominatorDeposits;
- nominator.depositsCount = nominatorDeposits.length;
+ account.totalDeposits += amount;
+ account.updatedAt = blockNumber;
- nominator.updatedAt = getBlockNumber(block);
+ cache.accounts.set(account.id, account);
- await ctx.store.save(nominator);
+ return cache;
}
-export async function processOperatorSlashedEvent(
- ctx: Ctx,
- apiAt: ApiDecoration<"promise">,
+export function processOperatorSlashedEvent(
+ cache: Cache,
block: CtxBlock,
extrinsic: CtxExtrinsic,
event: CtxEvent
) {
const operatorId = Number(event.args.operatorId);
- const operator = await getOrCreateOperator(ctx, block, operatorId);
+ const operator = getOrCreateOperator(cache, block, operatorId);
operator.currentTotalStake = BigInt(0);
operator.currentStorageFeeDeposit = BigInt(0);
operator.status = OperatorStatus.SLASHED;
operator.updatedAt = getBlockNumber(block);
- await ctx.store.save(operator);
+ cache.operators.set(operator.id, operator);
- const nominators = await ctx.store.findBy(Nominator, { operator });
- for (const nominator of nominators) {
- nominator.status = NominatorStatus.SLASHED;
- nominator.updatedAt = getBlockNumber(block);
+ Array.from(cache.nominators.values())
+ .filter((n) => n.operatorId === operator.id)
+ .map((n) => {
+ n.status = NominatorStatus.SLASHED;
+ n.updatedAt = getBlockNumber(block);
+ cache.nominators.set(n.id, n);
+ });
- await ctx.store.save(nominator);
- }
+ return cache;
}
-export async function processOperatorTaxCollectedEvent(
- ctx: Ctx,
- apiAt: ApiDecoration<"promise">,
+export function processOperatorTaxCollectedEvent(
+ cache: Cache,
block: CtxBlock,
extrinsic: CtxExtrinsic,
event: CtxEvent
) {
+ const blockNumber = getBlockNumber(block);
const operatorId = Number(event.args.operatorId);
- const operator = await getOrCreateOperator(ctx, block, operatorId);
+ const tax = BigInt(event.args.tax);
- operator.totalTaxCollected =
- operator.totalTaxCollected + BigInt(event.args.tax);
- operator.updatedAt = getBlockNumber(block);
+ const operator = getOrCreateOperator(cache, block, operatorId);
+ cache.operators.set(operator.id, operator);
+
+ const account = getOrCreateAccount(cache, block, operator.accountId);
+ cache.accounts.set(account.id, account);
+
+ const domain = getOrCreateDomain(cache, block, operator.domainId);
+ cache.domains.set(domain.id, domain);
+
+ operator.totalTaxCollected += tax;
+ operator.updatedAt = blockNumber;
+
+ cache.operators.set(operator.id, operator);
+
+ account.totalTaxCollected += tax;
+ account.updatedAt = blockNumber;
+
+ cache.accounts.set(account.id, account);
+
+ domain.totalTaxCollected += tax;
+
+ domain.updatedAt = blockNumber;
+
+ cache.domains.set(domain.id, domain);
+
+ return cache;
+}
+
+export function processOperatorRewardedEvent(
+ cache: Cache,
+ block: CtxBlock,
+ extrinsic: CtxExtrinsic,
+ event: CtxEvent
+) {
+ const operatorId = Number(event.args.operatorId);
+ const amount = BigInt(event.args.reward);
+
+ const operator = getOrCreateOperator(cache, block, operatorId);
+ const domain = getOrCreateDomain(cache, block, operator.domainId);
+
+ operator.totalRewardsCollected += amount;
+ cache.operators.set(operator.id, operator);
+
+ domain.totalRewardsCollected += amount;
+ cache.domains.set(domain.id, domain);
+
+ const operatorRewardedEvent = createOperatorRewardEvent(block, extrinsic, {
+ operatorId: operator.id,
+ domainId: operator.domainId,
+ amount,
+ });
+ cache.operatorRewardedEvents.set(
+ operatorRewardedEvent.id,
+ operatorRewardedEvent
+ );
- await ctx.store.save(operator);
+ return cache;
}
diff --git a/indexers/staking-squid/src/events/withdraw.ts b/indexers/staking-squid/src/events/withdraw.ts
new file mode 100644
index 000000000..523369708
--- /dev/null
+++ b/indexers/staking-squid/src/events/withdraw.ts
@@ -0,0 +1,52 @@
+import type { CtxBlock, CtxEvent, CtxExtrinsic } from "../processor";
+import {
+ createWithdrawal,
+ getOrCreateAccount,
+ getOrCreateDomain,
+ getOrCreateNominator,
+ getOrCreateOperator,
+} from "../storage";
+import { getCallSigner } from "../utils";
+import { Cache } from "../utils/cache";
+
+export function processWithdrewStakeEvent(
+ cache: Cache,
+ block: CtxBlock,
+ extrinsic: CtxExtrinsic,
+ event: CtxEvent
+) {
+ const address = getCallSigner(extrinsic.call);
+ const operatorId = Number(event.args.operatorId);
+
+ const shares = extrinsic.call
+ ? BigInt(extrinsic.call.args.shares)
+ : BigInt(0);
+
+ const account = getOrCreateAccount(cache, block, address);
+ cache.accounts.set(account.id, account);
+
+ const operator = getOrCreateOperator(cache, block, operatorId, {});
+ cache.operators.set(operator.id, operator);
+
+ const domain = getOrCreateDomain(cache, block, operator.domainId);
+ cache.domains.set(domain.id, domain);
+
+ const nominator = getOrCreateNominator(cache, block, extrinsic, operatorId, {
+ domainId: domain.id,
+ accountId: account.id,
+ operatorId: operator.id,
+ shares,
+ });
+ cache.nominators.set(nominator.id, nominator);
+
+ const withdrawal = createWithdrawal(block, extrinsic, {
+ domainId: domain.id,
+ accountId: account.id,
+ operatorId: operator.id,
+ nominatorId: nominator.id,
+ shares,
+ });
+ cache.withdrawals.set(withdrawal.id, withdrawal);
+
+ return cache;
+}
diff --git a/indexers/staking-squid/src/extrinsics/index.ts b/indexers/staking-squid/src/extrinsics/index.ts
index 1d49ffcd8..2d57c92f3 100644
--- a/indexers/staking-squid/src/extrinsics/index.ts
+++ b/indexers/staking-squid/src/extrinsics/index.ts
@@ -1,47 +1,42 @@
-import type { ApiDecoration } from "@polkadot/api/types";
-import type { Store } from "@subsquid/typeorm-store";
+import type { ApiPromise } from "@autonomys/auto-utils";
import { processEvents } from "../events";
-import type { ProcessorContext } from "../processor";
+import type { CtxBlock, CtxExtrinsic } from "../processor";
import { calls } from "../types";
+import { Cache } from "../utils/cache";
import { processDeregisterOperator, processRegisterOperator } from "./operator";
export async function processExtrinsics(
- ctx: ProcessorContext,
- apiAt: ApiDecoration<"promise">,
- block: ProcessorContext["blocks"][0],
- extrinsics: ProcessorContext["blocks"][0]["extrinsics"]
+ cache: Cache,
+ api: ApiPromise,
+ block: CtxBlock,
+ extrinsics: CtxExtrinsic[]
) {
for (let extrinsic of extrinsics) {
- await processExtrinsic(ctx, apiAt, block, extrinsic);
+ cache = await processExtrinsic(cache, api, block, extrinsic);
}
+ return cache;
}
export async function processExtrinsic(
- ctx: ProcessorContext,
- apiAt: ApiDecoration<"promise">,
- block: ProcessorContext["blocks"][0],
- extrinsic: ProcessorContext["blocks"][0]["extrinsics"][0]
+ cache: Cache,
+ api: ApiPromise,
+ block: CtxBlock,
+ extrinsic: CtxExtrinsic
) {
+ console.log("extrinsic", extrinsic.call?.name);
switch (extrinsic.call?.name) {
case calls.domains.registerOperator.name:
- return await processRegisterOperator(ctx, apiAt, block, extrinsic);
-
- case calls.domains.nominateOperator.name:
- break;
+ return processRegisterOperator(cache, block, extrinsic);
case calls.domains.deregisterOperator.name:
- return await processDeregisterOperator(ctx, apiAt, block, extrinsic);
+ return processDeregisterOperator(cache, block, extrinsic);
+ case calls.domains.nominateOperator.name:
case calls.domains.withdrawStake.name:
- break;
-
case calls.domains.unlockOperator.name:
- break;
-
case calls.domains.unlockFunds.name:
case calls.domains.unlockNominator.name:
- break;
default:
- return await processEvents(ctx, apiAt, block, extrinsic);
+ return await processEvents(cache, api, block, extrinsic);
}
}
diff --git a/indexers/staking-squid/src/extrinsics/operator.ts b/indexers/staking-squid/src/extrinsics/operator.ts
index 5ebf8a115..d7585cdb0 100644
--- a/indexers/staking-squid/src/extrinsics/operator.ts
+++ b/indexers/staking-squid/src/extrinsics/operator.ts
@@ -1,23 +1,30 @@
-import type { ApiDecoration } from "@polkadot/api/types";
-import type { Store } from "@subsquid/typeorm-store";
import { OperatorStatus } from "../model";
-import type { Ctx, CtxBlock, CtxExtrinsic } from "../processor";
-import { createOperator, getOrCreateOperator } from "../storage";
+import type { CtxBlock, CtxExtrinsic } from "../processor";
+import {
+ createDeposit,
+ createNominator,
+ createOperator,
+ getOrCreateAccount,
+ getOrCreateDomain,
+ getOrCreateOperator,
+} from "../storage";
import { events } from "../types";
import { getCallSigner } from "../utils";
+import { Cache } from "../utils/cache";
-export async function processRegisterOperator(
- ctx: Ctx,
- api: ApiDecoration<"promise">,
+export function processRegisterOperator(
+ cache: Cache,
block: CtxBlock,
extrinsic: CtxExtrinsic
) {
- const owner = getCallSigner(extrinsic.call);
- const domainId = extrinsic.call?.args.domainId;
+ const address = getCallSigner(extrinsic.call);
+ const domainId = Number(extrinsic.call?.args.domainId);
const operatorRegisteredEvent = extrinsic.events.find(
(e) => e.name === events.domains.operatorRegistered.name
);
+ if (!operatorRegisteredEvent) return cache;
+
const storageFeeDepositedEvent = extrinsic.events.find(
(e) => e.name === events.domains.storageFeeDeposited.name
);
@@ -25,44 +32,81 @@ export async function processRegisterOperator(
const operatorId = operatorRegisteredEvent
? Number(operatorRegisteredEvent.args.operatorId)
: 0;
+ const amount = extrinsic.call
+ ? BigInt(extrinsic.call.args.amount)
+ : BigInt(0);
+ const storageFeeDeposit = storageFeeDepositedEvent
+ ? BigInt(storageFeeDepositedEvent.args.amount)
+ : BigInt(0);
+
+ const domain = getOrCreateDomain(cache, block, domainId);
+ cache.domains.set(domain.id, domain);
+
+ const account = getOrCreateAccount(cache, block, address);
+ cache.accounts.set(account.id, account);
if (operatorRegisteredEvent) {
- const operator = await createOperator(ctx, block, {
- domainId,
- operatorId,
+ const operator = createOperator(block, operatorId, {
+ domainId: domain.id,
+ accountId: account.id,
signingKey: extrinsic.call?.args.config.signingKey,
- owner,
minimumNominatorStake: BigInt(
extrinsic.call?.args.config.minimumNominatorStake
),
nominationTax: extrinsic.call?.args.config.nominationTax,
- totalDeposits: extrinsic.call
- ? BigInt(extrinsic.call.args.amount)
- : BigInt(0),
+ totalDeposits: amount,
+ });
+ cache.operators.set(operator.id, operator);
+
+ const nominator = createNominator(block, extrinsic, operatorId, {
+ domainId: domain.id,
+ accountId: account.id,
+ operatorId: operator.id,
+ });
+ cache.nominators.set(nominator.id, nominator);
+
+ const deposit = createDeposit(block, extrinsic, {
+ domainId: domain.id,
+ accountId: account.id,
+ operatorId: operator.id,
+ nominatorId: nominator.id,
+ amount,
+ storageFeeDeposit,
});
+ cache.deposits.set(deposit.id, deposit);
+
+ domain.totalDeposits += amount;
+
+ cache.domains.set(domain.id, domain);
- await ctx.store.save(operator);
+ account.totalDeposits += amount;
+
+ cache.accounts.set(account.id, account);
}
+
+ return cache;
}
-export async function processDeregisterOperator(
- ctx: Ctx,
- api: ApiDecoration<"promise">,
+export function processDeregisterOperator(
+ cache: Cache,
block: CtxBlock,
extrinsic: CtxExtrinsic
) {
const operatorId = Number(extrinsic.call?.args.operatorId);
- const operator = await getOrCreateOperator(ctx, block, operatorId);
+ const operator = getOrCreateOperator(cache, block, operatorId);
const operatorDeregisteredEvent = extrinsic.events.find(
(e) => e.name === events.domains.operatorDeregistered.name
);
+ if (!operatorDeregisteredEvent) return cache;
if (operatorDeregisteredEvent) {
operator.currentTotalStake = BigInt(0);
operator.currentStorageFeeDeposit = BigInt(0);
operator.status = OperatorStatus.DEREGISTERED;
- await ctx.store.save(operator);
+ cache.operators.set(operator.id, operator);
}
+
+ return cache;
}
diff --git a/indexers/staking-squid/src/main.ts b/indexers/staking-squid/src/main.ts
index 91d396224..5f86bd2d4 100644
--- a/indexers/staking-squid/src/main.ts
+++ b/indexers/staking-squid/src/main.ts
@@ -1,13 +1,17 @@
-import { activate, ApiPromise } from "@autonomys/auto-utils";
-import { Store, TypeormDatabase } from "@subsquid/typeorm-store";
+import { createConnection } from "@autonomys/auto-utils";
+import { TypeormDatabase } from "@subsquid/typeorm-store";
+import { assertNotNull } from "@subsquid/util-internal";
import { processBlocks } from "./blocks";
-import { Ctx, processor } from "./processor";
+import { processor } from "./processor";
processor.run(new TypeormDatabase({ supportHotBlocks: true }), async (ctx) => {
- const api = await activate();
- await processChain(ctx, api);
+ console.log("Starting processor");
+
+ const api = await createConnection(
+ assertNotNull(process.env.RPC_CONSENSUS_HTTP, "No RPC endpoint supplied")
+ );
+
+ await processBlocks(ctx, api);
+
await api.disconnect();
});
-async function processChain(ctx: Ctx, api: ApiPromise) {
- await processBlocks(ctx, api);
-}
diff --git a/indexers/staking-squid/src/model/generated/index.ts b/indexers/staking-squid/src/model/generated/index.ts
index a952213ac..aa6a49f6f 100644
--- a/indexers/staking-squid/src/model/generated/index.ts
+++ b/indexers/staking-squid/src/model/generated/index.ts
@@ -1,4 +1,5 @@
export * from "./domain.model"
+export * from "./account.model"
export * from "./operator.model"
export * from "./_operatorStatus"
export * from "./nominator.model"
@@ -9,7 +10,6 @@ export * from "./withdrawal.model"
export * from "./_withdrawalStatus"
export * from "./operatorUnlockedFunds.model"
export * from "./operatorRewardEvent.model"
-export * from "./operatorFeesEarned.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 3a15f5ba4..a04b9f4ee 100644
--- a/indexers/staking-squid/src/processor.ts
+++ b/indexers/staking-squid/src/processor.ts
@@ -52,6 +52,9 @@ export const processor = new SubstrateBatchProcessor()
events.domains.operatorDeregistered.name,
events.domains.operatorNominated.name,
// deposit and stake
+ events.domains.withdrewStake.name,
+ events.domains.operatorUnlocked.name,
+ events.domains.fundsUnlocked.name,
events.domains.storageFeeDeposited.name,
// bundle
events.domains.bundleStored.name,
diff --git a/indexers/staking-squid/src/storage/account.ts b/indexers/staking-squid/src/storage/account.ts
new file mode 100644
index 000000000..4d106b156
--- /dev/null
+++ b/indexers/staking-squid/src/storage/account.ts
@@ -0,0 +1,31 @@
+import { Account } from "../model";
+import type { CtxBlock } from "../processor";
+import { getBlockNumber } from "../utils";
+import { Cache } from "../utils/cache";
+
+export const createAccount = (
+ block: CtxBlock,
+ address: string,
+ props: Partial
+): Account =>
+ new Account({
+ id: address,
+ totalDeposits: BigInt(0),
+ totalTaxCollected: BigInt(0),
+ ...props,
+ createdAt: getBlockNumber(block),
+ updatedAt: getBlockNumber(block),
+ });
+
+export const getOrCreateAccount = (
+ cache: Cache,
+ block: CtxBlock,
+ address: string,
+ props: Partial = {}
+): Account => {
+ const account = cache.accounts.get(address);
+
+ if (!account) return createAccount(block, address, props);
+
+ return account;
+};
diff --git a/indexers/staking-squid/src/storage/deposit.ts b/indexers/staking-squid/src/storage/deposit.ts
index 82a5ef40e..ac3f3098c 100644
--- a/indexers/staking-squid/src/storage/deposit.ts
+++ b/indexers/staking-squid/src/storage/deposit.ts
@@ -1,31 +1,16 @@
-import type { Store } from "@subsquid/typeorm-store";
import { randomUUID } from "crypto";
-import { Deposit, DepositStatus, Operator } from "../model";
-import type { Ctx, CtxBlock, CtxExtrinsic } from "../processor";
-import { getBlockNumber, getCallSigner, getTimestamp } from "../utils";
-import { getOrCreateNominator } from "./nominator";
-import { getOrCreateOperator } from "./operator";
+import { Deposit, DepositStatus } from "../model";
+import type { CtxBlock, CtxExtrinsic } from "../processor";
+import { getBlockNumber, getTimestamp } from "../utils";
+import { Cache } from "../utils/cache";
-export const createDeposit = async (
- ctx: Ctx,
+export const createDeposit = (
block: CtxBlock,
extrinsic: CtxExtrinsic,
props: Partial
-): Promise => {
- if (!props.account) props.account = getCallSigner(extrinsic.call);
- if (!props.operator)
- props.operator = await getOrCreateOperator(ctx, block, 0);
- if (!props.nominator && props.operator)
- props.nominator = await getOrCreateNominator(
- ctx,
- block,
- extrinsic,
- props.operator
- );
-
- const deposit = new Deposit({
+): Deposit =>
+ new Deposit({
id: randomUUID(),
- account: "st",
amount: BigInt(0),
storageFeeDeposit: BigInt(0),
status: DepositStatus.PENDING,
@@ -34,32 +19,3 @@ export const createDeposit = async (
timestamp: getTimestamp(block),
extrinsicHash: extrinsic.hash,
});
-
- await ctx.store.insert(deposit);
-
- const count = await ctx.store.count(Deposit);
- ctx.log.child("deposits").info(`count: ${count}`);
-
- return deposit;
-};
-
-export const getOrCreateDeposit = async (
- ctx: Ctx,
- block: CtxBlock,
- extrinsic: CtxExtrinsic,
- operator: Operator,
- props: Partial = {}
-): Promise => {
- const account = getCallSigner(extrinsic.call);
- const blockNumber = getBlockNumber(block);
- const deposit = await ctx.store.findOneBy(Deposit, { account, blockNumber });
-
- if (!deposit)
- return await createDeposit(ctx, block, extrinsic, {
- account,
- operator,
- ...props,
- });
-
- return deposit;
-};
diff --git a/indexers/staking-squid/src/storage/domain.ts b/indexers/staking-squid/src/storage/domain.ts
index 3f29135fc..62a148d3d 100644
--- a/indexers/staking-squid/src/storage/domain.ts
+++ b/indexers/staking-squid/src/storage/domain.ts
@@ -1,41 +1,39 @@
-import type { Store } from "@subsquid/typeorm-store";
-import { randomUUID } from "crypto";
import { Domain } from "../model";
-import type { Ctx, CtxBlock } from "../processor";
-import { getBlockNumber } from "../utils";
+import type { CtxBlock } from "../processor";
+import { domainUID, getBlockNumber } from "../utils";
+import { Cache } from "../utils/cache";
-export const createDomain = async (
- ctx: Ctx,
+export const createDomain = (
block: CtxBlock,
+ domainId: number | string,
props: Partial
-): Promise => {
- const domain = new Domain({
- id: randomUUID(),
- domainId: 0,
+): Domain =>
+ new Domain({
+ id: typeof domainId === "string" ? domainId : domainUID(domainId),
+ sortId: typeof domainId === "string" ? parseInt(domainId) : domainId,
completedEpoch: 0,
lastDomainBlockNumber: 0,
+ totalDeposits: BigInt(0),
+ totalTaxCollected: BigInt(0),
+ totalRewardsCollected: BigInt(0),
+ currentTotalStake: BigInt(0),
+ currentStorageFeeDeposit: BigInt(0),
...props,
createdAt: getBlockNumber(block),
updatedAt: getBlockNumber(block),
});
- await ctx.store.insert(domain);
-
- const count = await ctx.store.count(Domain);
- ctx.log.child("domains").info(`count: ${count}`);
-
- return domain;
-};
-
-export const getOrCreateDomain = async (
- ctx: Ctx,
+export const getOrCreateDomain = (
+ cache: Cache,
block: CtxBlock,
- domainId: number,
+ domainId: number | string,
props: Partial = {}
-): Promise => {
- const domain = await ctx.store.findOneBy(Domain, { domainId });
+): Domain => {
+ const domain = cache.domains.get(
+ typeof domainId === "string" ? domainId : domainUID(domainId)
+ );
- if (!domain) return await createDomain(ctx, block, { domainId, ...props });
+ if (!domain) return createDomain(block, domainId, props);
return domain;
};
diff --git a/indexers/staking-squid/src/storage/index.ts b/indexers/staking-squid/src/storage/index.ts
index d0257dfa9..a174753a8 100644
--- a/indexers/staking-squid/src/storage/index.ts
+++ b/indexers/staking-squid/src/storage/index.ts
@@ -1,5 +1,7 @@
+export * from "./account";
export * from "./deposit";
export * from "./domain";
export * from "./nominator";
export * from "./operator";
+export * from "./stats";
export * from "./withdrawal";
diff --git a/indexers/staking-squid/src/storage/nominator.ts b/indexers/staking-squid/src/storage/nominator.ts
index 24857b485..64fa6ea8f 100644
--- a/indexers/staking-squid/src/storage/nominator.ts
+++ b/indexers/staking-squid/src/storage/nominator.ts
@@ -1,59 +1,50 @@
-import type { Store } from "@subsquid/typeorm-store";
-import { randomUUID } from "crypto";
-import { Nominator, NominatorStatus, Operator } from "../model";
-import type { Ctx, CtxBlock, CtxExtrinsic } from "../processor";
-import { getBlockNumber, getCallSigner } from "../utils";
-import { getOrCreateOperator } from "./operator";
+import { Nominator, NominatorStatus } from "../model";
+import type { CtxBlock, CtxExtrinsic } from "../processor";
+import { getBlockNumber, getCallSigner, nominatorUID } from "../utils";
+import { Cache } from "../utils/cache";
-export const createNominator = async (
- ctx: Ctx,
+export const createNominator = (
block: CtxBlock,
extrinsic: CtxExtrinsic,
+ operatorId: number,
props: Partial
-): Promise => {
- if (!props.account) props.account = getCallSigner(extrinsic.call);
- if (!props.operator)
- props.operator = await getOrCreateOperator(ctx, block, 0);
+): Nominator => {
+ const address = getCallSigner(extrinsic.call);
- const nominator = new Nominator({
- id: randomUUID(),
- account: "st",
+ return new Nominator({
+ id: nominatorUID(operatorId, address),
shares: BigInt(0),
- deposits: [],
- withdrawals: [],
- depositsCount: 0,
- withdrawalsCount: 0,
totalDeposits: BigInt(0),
status: NominatorStatus.PENDING,
...props,
createdAt: getBlockNumber(block),
updatedAt: getBlockNumber(block),
});
-
- await ctx.store.insert(nominator);
-
- const count = await ctx.store.count(Nominator);
- ctx.log.child("nominators").info(`count: ${count}`);
-
- return nominator;
};
-export const getOrCreateNominator = async (
- ctx: Ctx,
+export const getOrCreateNominator = (
+ cache: Cache,
block: CtxBlock,
extrinsic: CtxExtrinsic,
- operator: Operator,
+ operatorId: number | string,
props: Partial = {}
-): Promise => {
- const account = getCallSigner(extrinsic.call);
- const nominator = await ctx.store.findOneBy(Nominator, { account, operator });
+): Nominator => {
+ const address = getCallSigner(extrinsic.call);
+ const nominator = cache.nominators.get(
+ typeof operatorId === "string"
+ ? operatorId
+ : nominatorUID(operatorId, address)
+ );
if (!nominator)
- return await createNominator(ctx, block, extrinsic, {
- account,
- operator,
- ...props,
- });
+ return createNominator(
+ block,
+ extrinsic,
+ typeof operatorId === "string" ? parseInt(operatorId) : operatorId,
+ {
+ ...props,
+ }
+ );
return nominator;
};
diff --git a/indexers/staking-squid/src/storage/operator.ts b/indexers/staking-squid/src/storage/operator.ts
index f5a3ea349..aaec301e2 100644
--- a/indexers/staking-squid/src/storage/operator.ts
+++ b/indexers/staking-squid/src/storage/operator.ts
@@ -1,22 +1,18 @@
-import type { Store } from "@subsquid/typeorm-store";
import { randomUUID } from "crypto";
-import { Operator, OperatorStatus } from "../model";
-import type { Ctx, CtxBlock } from "../processor";
-import { getBlockNumber } from "../utils";
-import { getOrCreateDomain } from "./domain";
+import { Operator, OperatorRewardEvent, OperatorStatus } from "../model";
+import type { CtxBlock, CtxExtrinsic } from "../processor";
+import { getBlockNumber, getTimestamp, operatorUID } from "../utils";
+import { Cache } from "../utils/cache";
-export const createOperator = async (
- ctx: Ctx,
+export const createOperator = (
block: CtxBlock,
+ operatorId: number | string,
props: Partial
-): Promise => {
- if (props.domainId) await getOrCreateDomain(ctx, block, props.domainId);
-
- const operator = new Operator({
- id: randomUUID(),
- operatorId: 0,
+): Operator =>
+ new Operator({
+ id: typeof operatorId === "string" ? operatorId : operatorUID(operatorId),
+ sortId: typeof operatorId === "string" ? parseInt(operatorId) : operatorId,
signingKey: "0x",
- owner: "st",
minimumNominatorStake: BigInt(0),
nominationTax: 0,
currentTotalStake: BigInt(0),
@@ -25,16 +21,9 @@ export const createOperator = async (
currentTotalShares: BigInt(0),
totalDeposits: BigInt(0),
totalTaxCollected: BigInt(0),
- deposits: [],
- nominators: [],
- withdrawals: [],
- operatorRewards: [],
- operatorFees: [],
+ totalRewardsCollected: BigInt(0),
rawStatus: JSON.stringify({}),
status: OperatorStatus.PENDING,
- nominatorsCount: 0,
- depositsCount: 0,
- withdrawalsCount: 0,
bundleCount: 0,
lastBundleAt: 0,
...props,
@@ -42,28 +31,30 @@ export const createOperator = async (
updatedAt: getBlockNumber(block),
});
- await ctx.store.insert(operator);
-
- const count = await ctx.store.count(Operator);
- ctx.log.child("operators").info(`count: ${count}`);
-
- return operator;
-};
-
-export const getOrCreateOperator = async (
- ctx: Ctx,
+export const getOrCreateOperator = (
+ cache: Cache,
block: CtxBlock,
- operatorId: number,
+ operatorId: number | string,
props: Partial = {}
-): Promise => {
- const operator = await ctx.store.findOneBy(Operator, { operatorId });
+): Operator => {
+ const operator = cache.operators.get(
+ typeof operatorId === "string" ? operatorId : operatorUID(operatorId)
+ );
- if (!operator)
- return await createOperator(ctx, block, {
- domainId: 0,
- operatorId,
- ...props,
- });
+ if (!operator) return createOperator(block, operatorId, props);
return operator;
};
+
+export const createOperatorRewardEvent = (
+ block: CtxBlock,
+ extrinsic: CtxExtrinsic,
+ props: Partial
+): OperatorRewardEvent =>
+ new OperatorRewardEvent({
+ id: randomUUID(),
+ ...props,
+ blockNumber: getBlockNumber(block),
+ timestamp: getTimestamp(block),
+ extrinsicHash: extrinsic.hash.toString(),
+ });
diff --git a/indexers/staking-squid/src/storage/stats.ts b/indexers/staking-squid/src/storage/stats.ts
new file mode 100644
index 000000000..af77f09b4
--- /dev/null
+++ b/indexers/staking-squid/src/storage/stats.ts
@@ -0,0 +1,125 @@
+import { randomUUID } from "crypto";
+import {
+ Domain,
+ Operator,
+ OperatorStatus,
+ Stats,
+ StatsPerDomain,
+ StatsPerOperator,
+} from "../model";
+import type { CtxBlock } from "../processor";
+import { getBlockNumber, getTimestamp } from "../utils";
+import { Cache } from "../utils/cache";
+
+export const createStatsPerOperator = (
+ cache: Cache,
+ block: CtxBlock,
+ domain: Domain,
+ operator: Operator
+): StatsPerOperator => {
+ const nominators = Array.from(cache.nominators.values()).filter(
+ (o) => o.domainId === domain.id
+ );
+ const deposits = Array.from(cache.deposits.values()).filter(
+ (o) => o.domainId === domain.id
+ );
+ const withdrawals = Array.from(cache.withdrawals.values()).filter(
+ (o) => o.domainId === domain.id
+ );
+ return new StatsPerOperator({
+ id: randomUUID(),
+ domainId: domain.id,
+ operatorId: operator.id,
+ totalStaked: operator.currentTotalStake,
+ totalFees: BigInt(0),
+ totalDeposits: operator.totalDeposits,
+ totalWithdrawals: BigInt(0),
+ allTimeHighStaked: BigInt(0),
+ nominatorsCount: nominators.length,
+ depositsCount: deposits.length,
+ withdrawalsCount: withdrawals.length,
+ blockNumber: getBlockNumber(block),
+ timestamp: getTimestamp(block),
+ });
+};
+
+export const createStatsPerDomain = (
+ cache: Cache,
+ block: CtxBlock,
+ domain: Domain
+): StatsPerDomain => {
+ const operators = Array.from(cache.operators.values()).filter(
+ (o) => o.domainId === domain.id
+ );
+ const nominators = Array.from(cache.nominators.values()).filter(
+ (o) => o.domainId === domain.id
+ );
+ const deposits = Array.from(cache.deposits.values()).filter(
+ (o) => o.domainId === domain.id
+ );
+ const withdrawals = Array.from(cache.withdrawals.values()).filter(
+ (o) => o.domainId === domain.id
+ );
+ const activeOperatorsCount = operators.filter(
+ (operator) => operator.status === OperatorStatus.REGISTERED
+ ).length;
+ const slashedOperatorsCount = operators.filter(
+ (operator) => operator.status === OperatorStatus.SLASHED
+ ).length;
+
+ return new StatsPerDomain({
+ id: randomUUID(),
+ domainId: domain.id,
+ totalStaked: domain.currentTotalStake,
+ totalFees: BigInt(0),
+ totalDeposits: domain.totalDeposits,
+ totalWithdrawals: BigInt(0),
+ allTimeHighStaked: BigInt(0),
+ operatorsCount: operators.length,
+ activeOperatorsCount,
+ slashedOperatorsCount,
+ nominatorsCount: nominators.length,
+ depositsCount: deposits.length,
+ withdrawalsCount: withdrawals.length,
+ blockNumber: getBlockNumber(block),
+ timestamp: getTimestamp(block),
+ });
+};
+
+export const createStats = (cache: Cache, block: CtxBlock): Stats => {
+ const operators = Array.from(cache.operators.values());
+
+ const activeOperatorsCount = operators.filter(
+ (operator) => operator.status === OperatorStatus.REGISTERED
+ ).length;
+ const slashedOperatorsCount = operators.filter(
+ (operator) => operator.status === OperatorStatus.SLASHED
+ ).length;
+
+ const totalStaked = operators.reduce(
+ (total, operator) => total + operator.currentTotalStake,
+ BigInt(0)
+ );
+ const totalDeposits = operators.reduce(
+ (total, operator) => total + operator.totalDeposits,
+ BigInt(0)
+ );
+
+ return new Stats({
+ id: randomUUID(),
+ totalStaked,
+ totalFees: BigInt(0),
+ totalDeposits,
+ totalWithdrawals: BigInt(0),
+ allTimeHighStaked: BigInt(0),
+ domainsCount: cache.domains.size,
+ operatorsCount: operators.length,
+ activeOperatorsCount,
+ slashedOperatorsCount,
+ nominatorsCount: cache.nominators.size,
+ depositsCount: cache.deposits.size,
+ withdrawalsCount: cache.withdrawals.size,
+ blockNumber: getBlockNumber(block),
+ timestamp: getTimestamp(block),
+ });
+};
diff --git a/indexers/staking-squid/src/storage/withdrawal.ts b/indexers/staking-squid/src/storage/withdrawal.ts
index 6d873abc6..c8f06d13b 100644
--- a/indexers/staking-squid/src/storage/withdrawal.ts
+++ b/indexers/staking-squid/src/storage/withdrawal.ts
@@ -1,31 +1,16 @@
-import type { Store } from "@subsquid/typeorm-store";
import { randomUUID } from "crypto";
-import { Operator, Withdrawal, WithdrawalStatus } from "../model";
-import type { Ctx, CtxBlock, CtxExtrinsic } from "../processor";
-import { getBlockNumber, getCallSigner, getTimestamp } from "../utils";
-import { getOrCreateNominator } from "./nominator";
-import { getOrCreateOperator } from "./operator";
+import { Withdrawal, WithdrawalStatus } from "../model";
+import type { CtxBlock, CtxExtrinsic } from "../processor";
+import { getBlockNumber, getTimestamp } from "../utils";
+import { Cache } from "../utils/cache";
-export const createWithdrawal = async (
- ctx: Ctx,
+export const createWithdrawal = (
block: CtxBlock,
extrinsic: CtxExtrinsic,
props: Partial
-): Promise => {
- if (!props.account) props.account = getCallSigner(extrinsic.call);
- if (!props.operator)
- props.operator = await getOrCreateOperator(ctx, block, 0);
- if (!props.nominator && props.operator)
- props.nominator = await getOrCreateNominator(
- ctx,
- block,
- extrinsic,
- props.operator
- );
-
- const withdrawal = new Withdrawal({
+): Withdrawal =>
+ new Withdrawal({
id: randomUUID(),
- account: "st",
shares: BigInt(0),
status: WithdrawalStatus.PENDING,
...props,
@@ -33,35 +18,3 @@ export const createWithdrawal = async (
timestamp: getTimestamp(block),
extrinsicHash: extrinsic.hash,
});
-
- await ctx.store.insert(withdrawal);
-
- const count = await ctx.store.count(Withdrawal);
- ctx.log.child("withdrawals").info(`count: ${count}`);
-
- return withdrawal;
-};
-
-export const getOrCreateWithdrawal = async (
- ctx: Ctx,
- block: CtxBlock,
- extrinsic: CtxExtrinsic,
- operator: Operator,
- props: Partial = {}
-): Promise => {
- const account = getCallSigner(extrinsic.call);
- const blockNumber = getBlockNumber(block);
- const withdrawal = await ctx.store.findOneBy(Withdrawal, {
- account,
- blockNumber,
- });
-
- if (!withdrawal)
- return await createWithdrawal(ctx, block, extrinsic, {
- account,
- operator,
- ...props,
- });
-
- return withdrawal;
-};
diff --git a/indexers/staking-squid/src/utils/cache.ts b/indexers/staking-squid/src/utils/cache.ts
new file mode 100644
index 000000000..8dcd7dbd3
--- /dev/null
+++ b/indexers/staking-squid/src/utils/cache.ts
@@ -0,0 +1,78 @@
+import type { Store } from "@subsquid/typeorm-store";
+import {
+ Account,
+ Deposit,
+ Domain,
+ Nominator,
+ Operator,
+ OperatorRewardEvent,
+ Stats,
+ StatsPerDomain,
+ StatsPerOperator,
+ Withdrawal,
+} from "../model";
+import type { Ctx } from "../processor";
+
+export type Cache = {
+ domains: Map;
+ accounts: Map;
+ operators: Map;
+ nominators: Map;
+ deposits: Map;
+ withdrawals: Map;
+
+ operatorRewardedEvents: Map;
+
+ stats: Map;
+ statsPerDomain: Map;
+ statsPerOperator: Map;
+};
+
+export const initCache: Cache = {
+ domains: new Map(),
+ accounts: new Map(),
+ operators: new Map(),
+ nominators: new Map(),
+ deposits: new Map(),
+ withdrawals: new Map(),
+
+ operatorRewardedEvents: new Map(),
+
+ stats: new Map(),
+ statsPerDomain: new Map(),
+ statsPerOperator: new Map(),
+};
+
+export const load = async (ctx: Ctx): Promise => {
+ const domains = await ctx.store.find(Domain);
+ const accounts = await ctx.store.find(Account);
+ const operators = await ctx.store.find(Operator);
+ const nominators = await ctx.store.find(Nominator);
+ const deposits = await ctx.store.find(Deposit);
+ const withdrawals = await ctx.store.find(Withdrawal);
+
+ return {
+ ...initCache,
+ domains: new Map(domains.map((d) => [d.id, d])),
+ accounts: new Map(accounts.map((a) => [a.id, a])),
+ operators: new Map(operators.map((o) => [o.id, o])),
+ nominators: new Map(nominators.map((n) => [n.id, n])),
+ deposits: new Map(deposits.map((d) => [d.id, d])),
+ withdrawals: new Map(withdrawals.map((w) => [w.id, w])),
+ };
+};
+
+export const save = async (ctx: Ctx, cache: Cache) => {
+ await ctx.store.save(Array.from(cache.domains.values()));
+ await ctx.store.save(Array.from(cache.accounts.values()));
+ await ctx.store.save(Array.from(cache.operators.values()));
+ await ctx.store.save(Array.from(cache.nominators.values()));
+ await ctx.store.save(Array.from(cache.deposits.values()));
+ await ctx.store.save(Array.from(cache.withdrawals.values()));
+
+ await ctx.store.save(Array.from(cache.operatorRewardedEvents.values()));
+
+ await ctx.store.save(Array.from(cache.stats.values()));
+ await ctx.store.save(Array.from(cache.statsPerDomain.values()));
+ await ctx.store.save(Array.from(cache.statsPerOperator.values()));
+};
diff --git a/indexers/staking-squid/src/utils/index.ts b/indexers/staking-squid/src/utils/index.ts
index 9727b5ff6..d4babbeca 100644
--- a/indexers/staking-squid/src/utils/index.ts
+++ b/indexers/staking-squid/src/utils/index.ts
@@ -17,3 +17,10 @@ export const getBlockNumber = (block: CtxBlock): number => block.header.height;
export const getTimestamp = (block: CtxBlock): Date =>
new Date(block.header.timestamp || 0);
+
+export const domainUID = (domainId: number): string => `${domainId}`;
+
+export const operatorUID = (operatorId: number): string => `${operatorId}`;
+
+export const nominatorUID = (operatorId: number, account: string): string =>
+ `${operatorId}-${account}`;