Skip to content

Commit

Permalink
Merge pull request #34 from Eigen-Explorer/feature/switch-operator-sh…
Browse files Browse the repository at this point in the history
…ares-to-stakers

Remove operator shares seeders, lookup staker shares for operators
  • Loading branch information
uditdc authored Apr 29, 2024
2 parents 54b4ef1 + 3c7d747 commit c8a5986
Show file tree
Hide file tree
Showing 9 changed files with 390 additions and 491 deletions.
472 changes: 240 additions & 232 deletions packages/api/src/routes/avs/avsController.ts

Large diffs are not rendered by default.

203 changes: 122 additions & 81 deletions packages/api/src/routes/operators/operatorController.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import type { Request, Response } from 'express';
import prisma from '../../utils/prismaClient';
// import { PaginationQuerySchema } from '../../schema/generic'
import { PaginationQuerySchema } from '../../schema/zod/schemas/paginationQuery';
import { handleAndReturnErrorResponse } from '../../schema/errors';
import type { Request, Response } from 'express'
import prisma from '../../utils/prismaClient'
import { PaginationQuerySchema } from '../../schema/zod/schemas/paginationQuery'
import { handleAndReturnErrorResponse } from '../../schema/errors'
import { StakerStrategyShares } from '@prisma/client'
import { IMap } from '../../schema/generic'

/**
* Route to get a list of all operators
Expand All @@ -11,54 +12,43 @@ import { handleAndReturnErrorResponse } from '../../schema/errors';
* @param res
*/
export async function getAllOperators(req: Request, res: Response) {
// Validate pagination query
const result = PaginationQuerySchema.safeParse(req.query);
if (!result.success) {
return handleAndReturnErrorResponse(req, res, result.error);
}
const { skip, take } = result.data;

try {
// Fetch count and record
const operatorCount = await prisma.operator.count();
const operatorRecords = await prisma.operator.findMany({
skip,
take,
include: { shares: true },
});

const operators = await Promise.all(
operatorRecords.map(async (operator) => {
let tvl = 0;
const shares = operator.shares;
const totalStakers = await prisma.staker.count({
where: { operatorAddress: operator.address },
});

shares.map((s) => {
tvl += Number(s.shares) / 1e18;
});

return {
...operator,
tvl,
totalStakers,
stakers: undefined,
};
})
);

res.send({
data: operators,
meta: {
total: operatorCount,
skip,
take,
},
});
} catch (error) {
handleAndReturnErrorResponse(req, res, error);
}
// Validate pagination query
const result = PaginationQuerySchema.safeParse(req.query)
if (!result.success) {
return handleAndReturnErrorResponse(req, res, result.error)
}
const { skip, take } = result.data

try {
// Fetch count and record
const operatorCount = await prisma.operator.count()
const operatorRecords = await prisma.operator.findMany({
skip,
take,
include: {
stakers: {
include: {
shares: true
}
}
}
})

const operators = operatorRecords.map((operator) =>
withOperatorTvl(operator)
)

res.send({
data: operators,
meta: {
total: operatorCount,
skip,
take
}
})
} catch (error) {
handleAndReturnErrorResponse(req, res, error)
}
}

/**
Expand All @@ -68,32 +58,83 @@ export async function getAllOperators(req: Request, res: Response) {
* @param res
*/
export async function getOperator(req: Request, res: Response) {
try {
const { id } = req.params;

const operator = await prisma.operator.findUniqueOrThrow({
where: { address: id },
include: { shares: true },
});

const totalStakers = await prisma.staker.count({
where: { operatorAddress: operator.address },
});

let tvl = 0;
const shares = operator.shares;

shares.map((s) => {
tvl += Number(s.shares) / 1e18;
});

res.send({
...operator,
tvl,
totalStakers,
stakers: undefined,
});
} catch (error) {
handleAndReturnErrorResponse(req, res, error);
}
try {
const { id } = req.params

const operator = await prisma.operator.findUniqueOrThrow({
where: { address: id },
include: {
stakers: {
include: {
shares: true
}
}
}
})

let tvl = 0

operator.stakers.map((staker) => {
staker.shares.map((s) => {
tvl += Number(s.shares) / 1e18
})
})

res.send(withOperatorTvlAndShares(operator))
} catch (error) {
handleAndReturnErrorResponse(req, res, error)
}
}

// Helper methods
export function withOperatorTvl(operator: {
stakers: { shares: StakerStrategyShares[] }[]
}) {
let tvl = 0

operator.stakers.map((staker) => {
staker.shares.map((s) => {
tvl += Number(s.shares) / 1e18
})
})

return {
...operator,
tvl,
totalStakers: operator.stakers.length,
stakers: undefined
}
}

export function withOperatorTvlAndShares(operator: {
stakers: { shares: StakerStrategyShares[] }[]
}) {
let tvl = 0
const sharesMap: IMap<string, string> = new Map()

operator.stakers.map((staker) => {
staker.shares.map((s) => {
if (!sharesMap.has(s.strategyAddress)) {
sharesMap.set(s.strategyAddress, '0')
}

sharesMap.set(
s.strategyAddress,
(BigInt(sharesMap.get(s.strategyAddress)) + BigInt(s.shares)).toString()
)

tvl += Number(s.shares) / 1e18
})
})

return {
...operator,
stakers: undefined,
shares: Array.from(sharesMap, ([strategyAddress, shares]) => ({
strategyAddress,
shares
})),
tvl,
totalStakers: operator.stakers.length
}
}
5 changes: 5 additions & 0 deletions packages/api/src/schema/generic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,8 @@ export const PaginationQuerySchema = Joi.object<{ skip: number; take: number }>(
take: Joi.number().default(12).min(1)
}
)

// Fix for broken types
export interface IMap<K, V> extends Map<K, V> {
get(key: K): V
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
Warnings:
- You are about to drop the `OperatorStrategyShares` table. If the table is not empty, all the data it contains will be lost.
*/
-- DropForeignKey
ALTER TABLE "OperatorStrategyShares" DROP CONSTRAINT "OperatorStrategyShares_operatorAddress_fkey";

-- DropTable
DROP TABLE "OperatorStrategyShares";
3 changes: 3 additions & 0 deletions packages/prisma/migrations/migration_lock.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Please do not edit this file manually
# It should be added in your version-control system (i.e. Git)
provider = "postgresql"
10 changes: 0 additions & 10 deletions packages/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -54,19 +54,9 @@ model Operator {
metadataX String?
avs AvsOperator[]
shares OperatorStrategyShares[]
stakers Staker[]
}

model OperatorStrategyShares {
Operator Operator @relation(fields: [operatorAddress], references: [address])
operatorAddress String
strategyAddress String
shares String
@@id([operatorAddress, strategyAddress])
}

model Staker {
address String @id @unique
Expand Down
2 changes: 0 additions & 2 deletions packages/seeder/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { seedOperators } from './seedOperators'
import { seedPods } from './seedPods'
import { seedValidatorsRestake } from './seedValidatorsRestake'
import { seedStakers } from './seedStakers'
import { seedOperatorShares } from './seedOperatorShares'
import { getViemClient } from './utils/viemClient'

console.log('Initializing seeder ...')
Expand All @@ -26,7 +25,6 @@ async function seedAvsLoop() {
await seedOperators(targetBlock)
await seedAvsOperators(targetBlock)
await seedStakers(targetBlock)
await seedOperatorShares(targetBlock)

await delay(120) // Wait for 2 minutes (120 seconds)
}
Expand Down
Loading

0 comments on commit c8a5986

Please sign in to comment.