Skip to content

Commit

Permalink
Subgraph fallbacks (#922)
Browse files Browse the repository at this point in the history
  • Loading branch information
gmbronco committed Sep 12, 2024
1 parent 03bf759 commit 9d9b90d
Show file tree
Hide file tree
Showing 22 changed files with 391 additions and 189 deletions.
5 changes: 5 additions & 0 deletions .changeset/smart-berries-watch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'backend': minor
---

Subgraph client will fallback to another URL on failure
4 changes: 4 additions & 0 deletions apps/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ export const schema = {
optional: true,
type: String,
},
SATSUMA_API_KEY: {
optional: true,
type: String,
},
WORKER_QUEUE_URL: {
optional: true,
type: String,
Expand Down
5 changes: 4 additions & 1 deletion config/arbitrum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ export default <NetworkData>{
},
subgraphs: {
startDate: '2021-08-23',
balancer: `https://gateway-arbitrum.network.thegraph.com/api/${env.THEGRAPH_API_KEY_BALANCER}/deployments/id/QmPbjY6L1NhPjpBv7wDTfG9EPx5FpCuBqeg1XxByzBTLcs`,
balancer: [
`https://gateway-arbitrum.network.thegraph.com/api/${env.THEGRAPH_API_KEY_BALANCER}/deployments/id/QmPbjY6L1NhPjpBv7wDTfG9EPx5FpCuBqeg1XxByzBTLcs`,
`https://subgraph.satsuma-prod.com/${env.SATSUMA_API_KEY}/balancer/balancer-v2-fantom/api`,
],
cowAmm: `https://gateway-arbitrum.network.thegraph.com/api/${env.THEGRAPH_API_KEY_BALANCER}/deployments/id/QmTSU862YAXb5XMhGsE7JCajuvf5FPiZjrdvC9nnbzd86x`,
beetsBar: 'https://',
blocks: 'https://api.studio.thegraph.com/query/48427/arbitrum-blocks/version/latest',
Expand Down
4 changes: 3 additions & 1 deletion config/avalanche.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ export default <NetworkData>{
},
subgraphs: {
startDate: '2023-06-06',
balancer: `https://gateway-arbitrum.network.thegraph.com/api/${env.THEGRAPH_API_KEY_BALANCER}/deployments/id/QmeJY1ZjmuJVPvmVghZSuiSxEx2a9kmpKnjr4Qw5hNdpLU`,
balancer: [
`https://gateway-arbitrum.network.thegraph.com/api/${env.THEGRAPH_API_KEY_BALANCER}/deployments/id/QmeJY1ZjmuJVPvmVghZSuiSxEx2a9kmpKnjr4Qw5hNdpLU`,
],
beetsBar: 'https://',
blocks: 'https://api.studio.thegraph.com/query/48427/avalanche-blocks/version/latest',
gauge: `https://gateway-arbitrum.network.thegraph.com/api/${env.THEGRAPH_API_KEY_BALANCER}/deployments/id/QmYCJJToWTY31LgsJG2vZTNkKWpQ7i91cTVYgPUBsJ5nQZ`,
Expand Down
2 changes: 1 addition & 1 deletion config/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export default <NetworkData>{
},
subgraphs: {
startDate: '2023-07-10',
balancer: `https://api.studio.thegraph.com/query/24660/balancer-base-v2/version/latest`,
balancer: [`https://api.studio.thegraph.com/query/24660/balancer-base-v2/version/latest`],
beetsBar: '',
blocks: 'https://api.studio.thegraph.com/query/48427/bleu-base-blocks/version/latest',
gauge: `https://api.studio.thegraph.com/query/24660/balancer-gauges-base/version/latest`,
Expand Down
5 changes: 4 additions & 1 deletion config/fantom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ export default <NetworkData>{
},
subgraphs: {
startDate: '2021-10-08',
balancer: `https://gateway-arbitrum.network.thegraph.com/api/${env.THEGRAPH_API_KEY_FANTOM}/deployments/id/QmYN8qV7PEokFeQvhhWMinYD5wsspP1Sc87pGKEvAmjSCJ`,
balancer: [
`https://gateway-arbitrum.network.thegraph.com/api/${env.THEGRAPH_API_KEY_FANTOM}/deployments/id/QmYN8qV7PEokFeQvhhWMinYD5wsspP1Sc87pGKEvAmjSCJ`,
`https://subgraph.satsuma-prod.com/${env.SATSUMA_API_KEY}/balancer/balancer-v2-arbitrum/api`,
],
beetsBar: `https://gateway-arbitrum.network.thegraph.com/api/${env.THEGRAPH_API_KEY_FANTOM}/deployments/id/QmXcxzZioHXV5ts2UcG6gNNEayoaZ9ip7D9JvPS88K2HXe`,
blocks: `https://gateway-arbitrum.network.thegraph.com/api/${env.THEGRAPH_API_KEY_FANTOM}/subgraphs/id/3drjZDpA9hAuYGA19ttEkhW432mVe2XHy5YarBDVYHbz`,
masterchef: `https://gateway-arbitrum.network.thegraph.com/api/${env.THEGRAPH_API_KEY_FANTOM}/deployments/id/QmZQJu1rxMEDwzZb5TSqDXjcFiS1DN8BRKCLKRv6ifEBhA`,
Expand Down
3 changes: 2 additions & 1 deletion config/fraxtal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ export default <NetworkData>{
},
subgraphs: {
startDate: '2024-05-22',
balancer:
balancer: [
'https://api.goldsky.com/api/public/project_clwhu1vopoigi01wmbn514m1z/subgraphs/balancer-fraxtal-v2/latest/gn',
],
beetsBar: '',
blocks: 'https://api.goldsky.com/api/public/project_clwhu1vopoigi01wmbn514m1z/subgraphs/fraxtal-blocks/1.0.0/gn',
gauge: 'https://api.goldsky.com/api/public/project_clwhu1vopoigi01wmbn514m1z/subgraphs/balancer-gauges-fraxtal/latest/gn',
Expand Down
4 changes: 3 additions & 1 deletion config/gnosis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ export default <NetworkData>{
},
subgraphs: {
startDate: '2021-08-23',
balancer: `https://gateway-arbitrum.network.thegraph.com/api/${env.THEGRAPH_API_KEY_BALANCER}/deployments/id/QmXXSKeLh14DnJgR1ncHhAHciqacfRshcHKXasAGy7LP4Y`,
balancer: [
`https://gateway-arbitrum.network.thegraph.com/api/${env.THEGRAPH_API_KEY_BALANCER}/deployments/id/QmXXSKeLh14DnJgR1ncHhAHciqacfRshcHKXasAGy7LP4Y`,
],
beetsBar: 'https://',
blocks: 'https://api.studio.thegraph.com/query/48427/gnosis-blocks/version/latest',
gauge: `https://gateway-arbitrum.network.thegraph.com/api/${env.THEGRAPH_API_KEY_BALANCER}/deployments/id/Qme9hQY1NZ8ReVDSSQb893s2fGpeLkgfwXd3YU5rndACaP`,
Expand Down
4 changes: 3 additions & 1 deletion config/mainnet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ export default <NetworkData>{
subgraphs: {
startDate: '2019-04-20',
cowAmm: `https://gateway-arbitrum.network.thegraph.com/api/${env.THEGRAPH_API_KEY_BALANCER}/deployments/id/QmUvfS6hqU3nGQxFFzxoMBkufYJ7Jh3cYdTUM64hucgqe7`,
balancer: `https://gateway-arbitrum.network.thegraph.com/api/${env.THEGRAPH_API_KEY_BALANCER}/deployments/id/QmQ5TT2yYBZgoUxsat3bKmNe5Fr9LW9YAtDs8aeuc1BRhj`,
balancer: [
`https://gateway-arbitrum.network.thegraph.com/api/${env.THEGRAPH_API_KEY_BALANCER}/deployments/id/QmQ5TT2yYBZgoUxsat3bKmNe5Fr9LW9YAtDs8aeuc1BRhj`,
],
beetsBar: 'https://',
blocks: 'https://api.studio.thegraph.com/query/48427/ethereum-blocks/version/latest',
gauge: `https://gateway-arbitrum.network.thegraph.com/api/${env.THEGRAPH_API_KEY_BALANCER}/deployments/id/QmdmQBHbBtwD6wNypHbuGKB1uKHpHNVuSHbo9FsvrMhXSn`,
Expand Down
2 changes: 1 addition & 1 deletion config/mode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export default <NetworkData>{
},
subgraphs: {
startDate: '2024-05-22',
balancer: `https://api.studio.thegraph.com/query/75376/balancer-mode-v2/version/latest`,
balancer: [`https://api.studio.thegraph.com/query/75376/balancer-mode-v2/version/latest`],
beetsBar: '',
blocks: 'https://api.studio.thegraph.com/query/48427/bleu-mode-blocks/version/latest',
gauge: `https://api.studio.thegraph.com/query/75376/balancer-gauges-mode/version/latest`,
Expand Down
5 changes: 4 additions & 1 deletion config/optimism.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ export default <NetworkData>{
},
subgraphs: {
startDate: '2022-01-01',
balancer: `https://gateway-arbitrum.network.thegraph.com/api/${env.THEGRAPH_API_KEY_BALANCER}/deployments/id/QmWUgkiUM5c3BW1Z51DUkZfnyQfyfesE8p3BRnEtA9vyPL`,
balancer: [
`https://gateway-arbitrum.network.thegraph.com/api/${env.THEGRAPH_API_KEY_BALANCER}/deployments/id/QmWUgkiUM5c3BW1Z51DUkZfnyQfyfesE8p3BRnEtA9vyPL`,
`https://subgraph.satsuma-prod.com/${env.SATSUMA_API_KEY}/balancer/balancer-v2-optimism/api`,
],
beetsBar: 'https://',
blocks: 'https://api.studio.thegraph.com/query/48427/optimism-blocks/version/latest',
gauge: `https://gateway-arbitrum.network.thegraph.com/api/${env.THEGRAPH_API_KEY_BALANCER}/deployments/id/Qmdtj1ix1nUCRtSoiyF7a3oKMSvrKT8KTEFJdep53EHtRy`,
Expand Down
4 changes: 3 additions & 1 deletion config/polygon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ export default <NetworkData>{
},
subgraphs: {
startDate: '2021-06-16',
balancer: `https://gateway-arbitrum.network.thegraph.com/api/${env.THEGRAPH_API_KEY_BALANCER}/deployments/id/QmUqS6BAVQgvstEsVrxuwsu1DwQdfAdj3Q6gz2j3DbUYQ9`,
balancer: [
`https://gateway-arbitrum.network.thegraph.com/api/${env.THEGRAPH_API_KEY_BALANCER}/deployments/id/QmUqS6BAVQgvstEsVrxuwsu1DwQdfAdj3Q6gz2j3DbUYQ9`,
],
beetsBar: 'https://',
blocks: 'https://api.studio.thegraph.com/query/48427/polygon-blocks/version/latest',
gauge: `https://gateway-arbitrum.network.thegraph.com/api/${env.THEGRAPH_API_KEY_BALANCER}/deployments/id/QmewSgLJf9TZt8trr61dECJhEGGyHxKFWbNQ3AnNZAdYyU`,
Expand Down
2 changes: 1 addition & 1 deletion config/sepolia.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export default <NetworkData>{
subgraphs: {
startDate: '2023-05-03',
cowAmm: 'https://api.studio.thegraph.com/proxy/75376/balancer-cow-amm-sepolia/version/latest',
balancer: 'https://api.studio.thegraph.com/query/24660/balancer-sepolia-v2/version/latest',
balancer: ['https://api.studio.thegraph.com/query/24660/balancer-sepolia-v2/version/latest'],
balancerV3: 'https://api.studio.thegraph.com/query/31386/balancer-v3-sepolia-8th/version/latest',
balancerPoolsV3: 'https://api.studio.thegraph.com/query/31386/balancer-pools-v3-sepolia-8th/version/latest',
beetsBar: 'https://',
Expand Down
2 changes: 1 addition & 1 deletion config/zkevm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export default <NetworkData>{
},
subgraphs: {
startDate: '2023-05-17',
balancer: `https://api.studio.thegraph.com/query/24660/balancer-polygon-zk-v2/version/latest`,
balancer: [`https://api.studio.thegraph.com/query/24660/balancer-polygon-zk-v2/version/latest`],
beetsBar: 'https://',
blocks: 'https://api.studio.thegraph.com/query/48427/bleu-polygon-zkevm-blocks/version/latest',
gauge: `https://api.studio.thegraph.com/query/24660/balancer-gauges-polygon-zk/version/latest`,
Expand Down
1 change: 1 addition & 0 deletions env.local
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ DEPLOYMENT_ENV=canary

# RPCs
ALCHEMY_API_KEY=
SATSUMA_API_KEY=

# Database
DATABASE_URL=postgresql://backend:let-me-in@localhost:5431/database?schema=public
Expand Down
2 changes: 1 addition & 1 deletion modules/network/network-config-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export interface NetworkData {
};
subgraphs: {
startDate: string;
balancer: string;
balancer: string[];
balancerV3?: string;
balancerPoolsV3?: string;
blocks: string;
Expand Down
11 changes: 7 additions & 4 deletions modules/protocol/protocol.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ import { Cache } from 'memory-cache';
import { Chain, PrismaLastBlockSyncedCategory, PrismaUserBalanceType } from '@prisma/client';
import _ from 'lodash';
import { networkContext } from '../network/network-context.service';
import { AllNetworkConfigs, AllNetworkConfigsKeyedOnChain } from '../network/network-config';
import { AllNetworkConfigs, AllNetworkConfigsKeyedOnChain, chainToIdMap } from '../network/network-config';
import { GqlProtocolMetricsAggregated, GqlProtocolMetricsChain } from '../../schema';
import { GraphQLClient } from 'graphql-request';
import { getSdk } from '../subgraphs/balancer-subgraph/generated/balancer-subgraph-types';
import axios from 'axios';
import { tokenService } from '../token/token.service';
import { getV2SubgraphClient } from '../subgraphs/balancer-subgraph';

interface LatestSyncedBlocks {
userWalletSyncBlock: string;
Expand Down Expand Up @@ -69,10 +70,12 @@ export class ProtocolService {
public async cacheProtocolMetrics(chain: Chain): Promise<GqlProtocolMetricsChain> {
const oneDayAgo = moment().subtract(24, 'hours').unix();

const client = new GraphQLClient(AllNetworkConfigsKeyedOnChain[chain].data.subgraphs.balancer);
const subgraphClient = getSdk(client);
const client = getV2SubgraphClient(
AllNetworkConfigsKeyedOnChain[chain].data.subgraphs.balancer,
Number(chainToIdMap[chain]),
);

const { balancers } = await subgraphClient.BalancerProtocolData({});
const { balancers } = await client.BalancerProtocolData({});
const { totalSwapFee, totalSwapVolume, poolCount } = balancers[0];

const pools = await prisma.prismaPool.findMany({
Expand Down
49 changes: 49 additions & 0 deletions modules/sources/subgraphs/retry-on-failure.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
export async function retryOnFailureWithRotation<T>(
sdkClients: any[],
fn: (sdk: any) => Promise<T>,
retries: number = 3,
): Promise<T> {
let attempts = 0;
let currentSdkIndex = 0;

while (attempts < retries) {
try {
const sdk = sdkClients[currentSdkIndex]; // Get the current SDK client
return await fn(sdk); // Try the operation using the current SDK
} catch (error) {
attempts += 1;
console.error(`Subgraph failed ${new URL(sdkClients[currentSdkIndex].url).host}:`, error);

if (attempts < retries) {
// Rotate to the next SDK client
currentSdkIndex = (currentSdkIndex + 1) % sdkClients.length;
console.log(`Retrying with ${new URL(sdkClients[currentSdkIndex].url).host}...`);
} else {
throw new Error('All SDK clients failed after retries.');
}
}
}

throw new Error('Unexpected failure, retries exhausted.');
}

export function wrapSdkWithRetryAndRotation<T extends object>(sdkClients: T[], retries: number = 3): T {
const wrappedSdk: Partial<T> = {};

// Use one SDK as a template for wrapping all functions
const sdk = sdkClients[0];

for (const key of Object.keys(sdk)) {
const value = (sdk as any)[key];

if (typeof value === 'function') {
// Wrap each SDK method to use retry with rotation
wrappedSdk[key as keyof T] = ((...args: any[]) =>
retryOnFailureWithRotation(sdkClients, (sdk) => value.apply(sdk, args), retries)) as T[keyof T];
} else {
wrappedSdk[key as keyof T] = value;
}
}

return wrappedSdk as T;
}
26 changes: 26 additions & 0 deletions modules/sources/subgraphs/subgraph-service-base.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { GraphQLClient } from 'graphql-request';
import { Cache, CacheClass } from 'memory-cache';
import { retryOnFailureWithRotation } from './retry-on-failure';

export class SubgraphServiceBase<TSdk> {
protected cache: CacheClass<string, any>;
private sdks: TSdk[];

constructor(
subgraphUrl: string | string[],
protected chainId: number,
private getSdk: (client: GraphQLClient) => TSdk,
) {
this.cache = new Cache<string, any>();

if (Array.isArray(subgraphUrl)) {
this.sdks = subgraphUrl.map((url) => this.getSdk(new GraphQLClient(url)));
} else {
this.sdks = [this.getSdk(new GraphQLClient(subgraphUrl))];
}
}

protected async retryOnFailure<T>(fn: (sdk: TSdk) => Promise<T>, retries: number = 3): Promise<T> {
return retryOnFailureWithRotation(this.sdks, fn, retries);
}
}
Loading

0 comments on commit 9d9b90d

Please sign in to comment.