Skip to content

Commit

Permalink
Merge pull request #1547 from balancer/v3-canary
Browse files Browse the repository at this point in the history
publish to prod
  • Loading branch information
gmbronco authored Jan 29, 2025
2 parents 454a911 + 3527f3f commit 71db3c5
Show file tree
Hide file tree
Showing 44 changed files with 210 additions and 896 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# backend

## 1.31.0

### Minor Changes

- e047a6c: replacing blocks subgraph with data from events

### Patch Changes

- a29f079: hgETH APR

## 1.30.0

### Minor Changes
Expand Down
9 changes: 4 additions & 5 deletions apps/api/gql/generated-schema-ast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3682,7 +3682,6 @@ export const schema = gql`
type Mutation {
beetsPoolLoadReliquarySnapshotsForAllFarms: String!
beetsSyncFbeetsRatio: String!
cacheAverageBlockTime: String!
poolLoadOnChainDataForAllPools(chains: [GqlChain!]!): [GqlPoolMutationResult!]!
poolLoadSnapshotsForPools(poolIds: [String!]!, reload: Boolean): String!
poolReloadAllPoolAprs(chain: GqlChain!): String!
Expand Down Expand Up @@ -3724,10 +3723,10 @@ export const schema = gql`
type Query {
beetsGetFbeetsRatio: String!
beetsPoolGetReliquaryFarmSnapshots(id: String!, range: GqlPoolSnapshotDataRange!): [GqlReliquaryFarmSnapshot!]!
blocksGetAverageBlockTime: Float!
blocksGetBlocksPerDay: Float!
blocksGetBlocksPerSecond: Float!
blocksGetBlocksPerYear: Float!
blocksGetAverageBlockTime: Float! @deprecated
blocksGetBlocksPerDay: Float! @deprecated
blocksGetBlocksPerSecond: Float! @deprecated
blocksGetBlocksPerYear: Float! @deprecated
contentGetNewsItems(chain: GqlChain): [GqlContentNewsItem!]!
latestSyncedBlocks: GqlLatestSyncedBlocks!
Expand Down
6 changes: 4 additions & 2 deletions apps/api/gql/generated-schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2452,7 +2452,6 @@ export interface Mutation {
__typename?: 'Mutation';
beetsPoolLoadReliquarySnapshotsForAllFarms: Scalars['String'];
beetsSyncFbeetsRatio: Scalars['String'];
cacheAverageBlockTime: Scalars['String'];
poolLoadOnChainDataForAllPools: Array<GqlPoolMutationResult>;
poolLoadSnapshotsForPools: Scalars['String'];
poolReloadAllPoolAprs: Scalars['String'];
Expand Down Expand Up @@ -2558,9 +2557,13 @@ export interface Query {
__typename?: 'Query';
beetsGetFbeetsRatio: Scalars['String'];
beetsPoolGetReliquaryFarmSnapshots: Array<GqlReliquaryFarmSnapshot>;
/** @deprecated Field no longer supported */
blocksGetAverageBlockTime: Scalars['Float'];
/** @deprecated Field no longer supported */
blocksGetBlocksPerDay: Scalars['Float'];
/** @deprecated Field no longer supported */
blocksGetBlocksPerSecond: Scalars['Float'];
/** @deprecated Field no longer supported */
blocksGetBlocksPerYear: Scalars['Float'];
contentGetNewsItems: Array<GqlContentNewsItem>;
latestSyncedBlocks: GqlLatestSyncedBlocks;
Expand Down Expand Up @@ -5317,7 +5320,6 @@ export type MutationResolvers<
> = ResolversObject<{
beetsPoolLoadReliquarySnapshotsForAllFarms?: Resolver<ResolversTypes['String'], ParentType, ContextType>;
beetsSyncFbeetsRatio?: Resolver<ResolversTypes['String'], ParentType, ContextType>;
cacheAverageBlockTime?: Resolver<ResolversTypes['String'], ParentType, ContextType>;
poolLoadOnChainDataForAllPools?: Resolver<
Array<ResolversTypes['GqlPoolMutationResult']>,
ParentType,
Expand Down
1 change: 0 additions & 1 deletion apps/api/gql/resolvers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ export const resolvers = {
...vebalResolver.Query,
},
Mutation: {
...blocksResolver.Mutation,
...contentResolver.Mutation,
...poolResolver.Mutation,
...protocolResolver.Mutation,
Expand Down
42 changes: 27 additions & 15 deletions apps/api/gql/resolvers/blocks.resolvers.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,42 @@
import { Resolvers } from '../generated-schema';
import { isAdminRoute } from '../../../../modules/auth/auth-context';
import { blocksSubgraphService } from '../../../../modules/subgraphs/blocks-subgraph/blocks-subgraph.service';
import { chainIdToChain } from '../../../../modules/network/chain-id-to-chain';
import { blockNumbers } from '../../../../modules/block-numbers';
import { GraphQLError } from 'graphql';
import { env } from '../../../env';

const balancerResolvers: Resolvers = {
Query: {
blocksGetAverageBlockTime: async (parent, {}, context) => {
return blocksSubgraphService.getAverageBlockTime();
const chainId = context.chainId || env.DEFAULT_CHAIN_ID;
const chain = chainIdToChain[chainId];

const service = blockNumbers();
const blocksPerDay = await service.getBlocksPerDay(chain);
return 86400 / blocksPerDay;
},
blocksGetBlocksPerSecond: async (parent, {}, context) => {
const avgBlockTime = await blocksSubgraphService.getAverageBlockTime();
return 1 / avgBlockTime;
const chainId = context.chainId || env.DEFAULT_CHAIN_ID;
const chain = chainIdToChain[chainId];

const service = blockNumbers();
const blocksPerDay = await service.getBlocksPerDay(chain);
return blocksPerDay / 86400;
},
blocksGetBlocksPerDay: async (parent, {}, context) => {
return blocksSubgraphService.getBlocksPerDay();
const chainId = context.chainId || env.DEFAULT_CHAIN_ID;
const chain = chainIdToChain[chainId];

const service = blockNumbers();
const blocksPerDay = await service.getBlocksPerDay(chain);
return blocksPerDay;
},
blocksGetBlocksPerYear: async (parent, {}, context) => {
return blocksSubgraphService.getBlocksPerYear();
},
},
Mutation: {
cacheAverageBlockTime: async (parent, {}, context) => {
isAdminRoute(context);

await blocksSubgraphService.cacheAverageBlockTime();
const chainId = context.chainId || env.DEFAULT_CHAIN_ID;
const chain = chainIdToChain[chainId];

return 'success';
const service = blockNumbers();
const blocksPerDay = await service.getBlocksPerDay(chain);
return blocksPerDay * 365;
},
},
};
Expand Down
12 changes: 4 additions & 8 deletions apps/api/gql/schema/blocks.gql
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
extend type Query {
blocksGetAverageBlockTime: Float!
blocksGetBlocksPerSecond: Float!
blocksGetBlocksPerDay: Float!
blocksGetBlocksPerYear: Float!
}

extend type Mutation {
cacheAverageBlockTime: String!
blocksGetAverageBlockTime: Float! @deprecated
blocksGetBlocksPerSecond: Float! @deprecated
blocksGetBlocksPerDay: Float! @deprecated
blocksGetBlocksPerYear: Float! @deprecated
}
4 changes: 0 additions & 4 deletions apps/worker/job-handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import * as Sentry from '@sentry/node';
import { Express, NextFunction } from 'express';
import { tokenService } from '../../modules/token/token.service';
import { poolService } from '../../modules/pool/pool.service';
import { blocksSubgraphService } from '../../modules/subgraphs/blocks-subgraph/blocks-subgraph.service';
import { userService } from '../../modules/user/user.service';
import { protocolService } from '../../modules/protocol/protocol.service';
import { datastudioService } from '../../modules/datastudio/datastudio.service';
Expand Down Expand Up @@ -177,9 +176,6 @@ const setupJobHandlers = async (name: string, chainId: string, res: any, next: N
next,
);
break;
case 'cache-average-block-time':
await runIfNotAlreadyRunning(name, chainId, () => blocksSubgraphService.cacheAverageBlockTime(), res, next);
break;
case 'sync-staking-for-pools':
await runIfNotAlreadyRunning(name, chainId, () => StakingController().syncStaking(chain), res, next);
break;
Expand Down
5 changes: 0 additions & 5 deletions codegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,6 @@ const files = {
},
},
},
['modules/subgraphs/blocks-subgraph/generated/blocks-subgraph-types.ts']: {
schema: config.MAINNET.subgraphs.blocks,
documents: 'modules/subgraphs/blocks-subgraph/block-subgraph-queries.graphql',
...defaults.types,
},
['modules/subgraphs/beets-bar-subgraph/generated/beets-bar-subgraph-types.ts']: {
schema: config.FANTOM.subgraphs.beetsBar,
documents: 'modules/subgraphs/beets-bar-subgraph/beets-bar-subgraph-queries.graphql',
Expand Down
6 changes: 6 additions & 0 deletions config/mainnet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,12 @@ export default <NetworkData>{
path: 'value',
isIbYield: true,
},
hgETH: {
tokenAddress: '0xc824a08db624942c5e5f330d56530cd1598859fd',
sourceUrl: 'https://universe.kelpdao.xyz/rseth/gainApy',
path: 'hgETH',
isIbYield: true,
},
sDOLA: {
tokenAddress: '0xb45ad160634c528cc3d2926d9807104fa3157305',
sourceUrl: 'https://www.inverse.finance/api/dola-staking',
Expand Down
5 changes: 2 additions & 3 deletions modules/actions/pool/update-liquidity.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Chain } from '@prisma/client';
import { BlockNumbersSubgraphClient, V3VaultSubgraphClient } from '../../sources/subgraphs';
import { V3VaultSubgraphClient } from '../../sources/subgraphs';
import { V2SubgraphClient } from '../../subgraphs/balancer-subgraph';
import { getLiquidityAndSharesAtTimestamp } from '../../sources/enrichers/get-liquidity-and-shares-at-timestamp';
import { daysAgo, hoursAgo } from '../../common/time';
Expand All @@ -22,12 +22,11 @@ import _ from 'lodash';
export const updateLiquidity24hAgo = async (
ids: string[],
subgraphClient: V2SubgraphClient | V3VaultSubgraphClient,
blocksClient: BlockNumbersSubgraphClient,
chain: Chain,
) => {
// Get liquidity data
const ts = chain === Chain.SEPOLIA ? hoursAgo(1) : daysAgo(1);
const data = await getLiquidityAndSharesAtTimestamp(ids, subgraphClient, blocksClient, ts);
const data = await getLiquidityAndSharesAtTimestamp(chain, ids, subgraphClient, ts);
if (!data) return;

// Update liquidity data
Expand Down
8 changes: 4 additions & 4 deletions modules/actions/snapshots/pool-snapshot-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ import _ from 'lodash';
import { Chain, PrismaPoolSnapshot } from '@prisma/client';
import { prismaBulkExecuteOperations } from '../../../prisma/prisma-util';
import { prismaPoolWithExpandedNesting } from '../../../prisma/prisma-types';
import { blocksSubgraphService } from '../../subgraphs/blocks-subgraph/blocks-subgraph.service';
import { TokenHistoricalPrices } from '../../token/lib/coingecko-data.service';
import { V2SubgraphClient } from '../../subgraphs/balancer-subgraph';
import { blockNumbers } from '../../block-numbers';

export class PoolSnapshotService {
constructor(
Expand Down Expand Up @@ -212,10 +212,10 @@ export class PoolSnapshotService {
}
}

const dailyBlocks = await blocksSubgraphService.getDailyBlocks(numDays);
const dailyBlocks = await blockNumbers().getDailyBlocks(this.chain, numDays);

for (const block of dailyBlocks) {
const startTimestamp = parseInt(block.timestamp);
const startTimestamp = moment(block.timestamp).utc().startOf('day').unix();
const endTimestamp = startTimestamp + 86400;
const swapsForDay = swaps.filter(
(swap) =>
Expand All @@ -240,7 +240,7 @@ export class PoolSnapshotService {

const { pool: poolAtBlock } = await this.balancerSubgraphService.legacyService.getPool({
id: poolId,
block: { number: parseInt(block.number) },
block: { number: block.number },
});

if (!poolAtBlock) {
Expand Down
60 changes: 60 additions & 0 deletions modules/block-numbers/block-numbers.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { expect, test, describe, mock, beforeEach } from 'bun:test';
import { blockNumbers } from './index';
import { Chain } from '@prisma/client';

describe('blockNumbers', () => {
const mockEvents = {
$queryRawUnsafe: mock(() => {}),
};

beforeEach(() => {
mockEvents.$queryRawUnsafe.mockReset();
});

describe('getBlock', () => {
test('should return block number for given timestamp', async () => {
const mockEvent = [{ blockNumber: 12345 }];
mockEvents.$queryRawUnsafe.mockResolvedValue(mockEvent);

const service = blockNumbers(mockEvents as any);
const result = await service.getBlock(Chain.MAINNET, 1000);

expect(result).toBe(12345);
});

test('should return undefined if no event found', async () => {
mockEvents.$queryRawUnsafe.mockResolvedValue([]);

const service = blockNumbers(mockEvents as any);
const result = await service.getBlock(Chain.MAINNET, 1000);

expect(result).toBeUndefined();
});
});

describe('getBlocksPerDay', () => {
test('should return count of blocks in last 24 hours', async () => {
mockEvents.$queryRawUnsafe.mockResolvedValue([{ max: 4000, min: 1000 }]);

const service = blockNumbers(mockEvents as any);
const result = await service.getBlocksPerDay(Chain.MAINNET);

expect(result).toBe(1000);
});
});

describe('getDailyBlocks', () => {
test('should return daily block numbers', async () => {
const mockBlocks = [
{ timestamp: 1000, number: 12345 },
{ timestamp: 2000, number: 12445 },
];
mockEvents.$queryRawUnsafe.mockResolvedValue(mockBlocks);

const service = blockNumbers(mockEvents as any);
const result = await service.getDailyBlocks(Chain.MAINNET, 2);

expect(result).toEqual(mockBlocks);
});
});
});
67 changes: 67 additions & 0 deletions modules/block-numbers/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { Chain, Prisma } from '@prisma/client';
import { prisma } from '../../prisma/prisma-client';

export const blockNumbers = (db = prisma) => ({
/**
* Get the block number for a given timestamp
*
* @param chain
* @param timestamp
* @returns
*/
async getBlock(chain: Chain, timestamp: number) {
const [event] = await db.$queryRawUnsafe<{ blockNumber: number }[]>(`
SELECT "blockNumber"
FROM "PartitionedPoolEvent"
WHERE chain = '${chain}'
AND "blockTimestamp" <= ${timestamp}::integer
ORDER BY "blockTimestamp" DESC
LIMIT 1;
`);

return event?.blockNumber;
},
/**
* Gets the number of blocks per day meaning the speed of the chain.
* Calculated from average number of blocks per day for the last 3 days.
*
* @param chain
* @param timestamp
* @returns
*/
async getBlocksPerDay(chain: Chain) {
const [blocks] = await db.$queryRawUnsafe<{ max: number; min: number }[]>(`
SELECT
MAX("blockNumber") as max,
MIN("blockNumber") as min
FROM "PartitionedPoolEvent"
WHERE chain = '${chain}'
AND "blockTimestamp" >= (EXTRACT(EPOCH FROM NOW()) - 86400 * 3)::integer;
`);

const range = blocks.max - blocks.min;

return Math.ceil(range / 3);
},
/**
* Block numbers for the last n days closest to 00:00:00 (UTC)
*
* @param chain
* @param days
* @returns
*/
async getDailyBlocks(chain: Chain, days: number) {
const blocks = await db.$queryRawUnsafe<{ timestamp: number; number: number }[]>(`
SELECT
("blockTimestamp"/86400)::INTEGER * 86400 as timestamp,
MIN("blockNumber") as number
FROM "PartitionedPoolEvent"
WHERE chain = '${chain}'
AND "blockTimestamp" >= ((EXTRACT(EPOCH FROM NOW()) / 86400)::integer * 86400 - 86400 * ${days})::integer
GROUP BY 1
ORDER BY 1 DESC;
`);

return blocks;
},
});
Loading

0 comments on commit 71db3c5

Please sign in to comment.