Skip to content

Commit

Permalink
Merge branch 'v3-canary' into feature/userbalances-on-pools
Browse files Browse the repository at this point in the history
  • Loading branch information
franzns committed Dec 1, 2023
2 parents 06c2a0f + 97589a1 commit e6ed07d
Show file tree
Hide file tree
Showing 15 changed files with 390 additions and 240 deletions.
19 changes: 6 additions & 13 deletions app.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { loadRestRoutesBeethoven } from './modules/beethoven/loadRestRoutes';
import { loadRestRoutesBalancer } from './modules/balancer/loadRestRoutes';
import { loadRestRoutes } from './modules/common/loadRestRoutes';
import { env } from './app/env';
import createExpressApp from 'express';
import { corsMiddleware } from './app/middleware/corsMiddleware';
Expand All @@ -12,10 +11,8 @@ import {
ApolloServerPluginLandingPageGraphQLPlayground,
ApolloServerPluginUsageReporting,
} from 'apollo-server-core';
import { ApolloServerPlugin } from 'apollo-server-plugin-base';
import { beethovenSchema } from './graphql_schema_generated_beethoven';
import { balancerSchema } from './graphql_schema_generated_balancer';
import { balancerResolvers, beethovenResolvers } from './app/gql/resolvers';
import { schema } from './graphql_schema_generated';
import { resolvers } from './app/gql/resolvers';
import helmet from 'helmet';
import GraphQLJSON from 'graphql-type-json';
import * as Sentry from '@sentry/node';
Expand Down Expand Up @@ -76,11 +73,7 @@ async function startServer() {
app.use(contextMiddleware);
app.use(sessionMiddleware);

if (env.PROTOCOL === 'beethoven') {
loadRestRoutesBeethoven(app);
} else if (env.PROTOCOL === 'balancer') {
loadRestRoutesBalancer(app);
}
loadRestRoutes(app);

const httpServer = http.createServer(app);

Expand All @@ -103,9 +96,9 @@ async function startServer() {
const server = new ApolloServer({
resolvers: {
JSON: GraphQLJSON,
...(env.PROTOCOL === 'beethoven' ? beethovenResolvers : balancerResolvers),
...resolvers,
},
typeDefs: env.PROTOCOL === 'beethoven' ? beethovenSchema : balancerSchema,
typeDefs: schema,
introspection: true,
plugins,
context: ({ req }) => req.context,
Expand Down
8 changes: 2 additions & 6 deletions app/gql/resolvers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,5 @@ import { loadFilesSync } from '@graphql-tools/load-files';
import path from 'path';
import { mergeResolvers } from '@graphql-tools/merge';

const balancerResolversArray = loadFilesSync(path.join(__dirname, '../../modules/!(beethoven)/**/*.resolvers.*'));

const beethovenResolversArray = loadFilesSync(path.join(__dirname, '../../modules/!(balancer)/**/*.resolvers.*'));

export const balancerResolvers = mergeResolvers(balancerResolversArray);
export const beethovenResolvers = mergeResolvers(beethovenResolversArray);
const resolversArray = loadFilesSync(path.join(__dirname, '../../modules/**/*.resolvers.*'));
export const resolvers = mergeResolvers(resolversArray);
24 changes: 3 additions & 21 deletions codegen.yml
Original file line number Diff line number Diff line change
Expand Up @@ -137,31 +137,13 @@ generates:
schema: ${USER_SNAPSHOT_SUBGRAPH}
plugins:
- schema-ast
graphql_schema_generated_balancer.ts:
schema:
- ./modules/**/*.gql
- '!./modules/beethoven/beets.gql'
- '!./modules/**/*.beets.gql'
plugins:
- add:
content: |
import { gql } from 'apollo-server-express';
export const balancerSchema = gql`
#\n# THIS FILE IS AUTOGENERATED — DO NOT EDIT IT\n#
- schema-ast
- add:
placement: 'append'
content: '`;'
graphql_schema_generated_beethoven.ts:
schema:
- ./modules/**/*.gql
- '!./modules/balancer/balancer.gql'
- '!./modules/**/*.balancer.gql'
graphql_schema_generated.ts:
schema: ./modules/**/*.gql
plugins:
- add:
content: |
import { gql } from 'apollo-server-express';
export const beethovenSchema = gql`
export const schema = gql`
#\n# THIS FILE IS AUTOGENERATED — DO NOT EDIT IT\n#
- schema-ast
- add:
Expand Down
5 changes: 0 additions & 5 deletions modules/balancer/loadRestRoutes.ts

This file was deleted.

12 changes: 7 additions & 5 deletions modules/coingecko/coingecko.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,10 @@ interface CoinId {
that happen.
*/
const tokensPerInterval = env.COINGECKO_API_KEY ? ((env.DEPLOYMENT_ENV as DeploymentEnv) === 'main' ? 10 : 5) : 3;
const requestRateLimiter = new RateLimiter({ tokensPerInterval, interval: 'minute' });
const tokensPerMinute = env.COINGECKO_API_KEY ? 10 : 3;
const requestRateLimiter = new RateLimiter({ tokensPerInterval: tokensPerMinute, interval: 'minute' });
//max 10 addresses per request because of URI size limit, pro is max 180 because of URI limit
const addressChunkSize = env.COINGECKO_API_KEY ? 180 : 20;

export class CoingeckoService {
private readonly baseUrl: string;
Expand Down Expand Up @@ -104,10 +106,10 @@ export class CoingeckoService {
* Rate limit for the CoinGecko API is 10 calls each second per IP address.
*/
public async getTokenPrices(addresses: string[]): Promise<TokenPrices> {
//max 180 addresses per request because of URI size limit
const addressesPerRequest = 180;
const addressesPerRequest = addressChunkSize;
try {
if (addresses.length / addressesPerRequest > 10) throw new Error('Too many requests for rate limit.');
// if (addresses.length / addressesPerRequest > tokensPerMinute)
// throw new Error('Too many requests for rate limit.');

const tokenDefinitions = await tokenService.getTokenDefinitions([networkContext.chain]);
const mapped = addresses.map((address) => this.getMappedTokenDetails(address, tokenDefinitions));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@ import { Express } from 'express';
import { beetsGetCirculatingSupply } from '../beets/lib/beets';
import { tokenService } from '../token/token.service';

export function loadRestRoutesBeethoven(app: Express) {
export function loadRestRoutes(app: Express) {
app.use('/health', (req, res) => res.sendStatus(200));
app.use('/circulating_supply', (req, res) => {
beetsGetCirculatingSupply().then((result) => {
res.send(result);
});
});

app.use('/late-quartet', async (req, res) => {
const tokenPrices = await tokenService.getTokenPrices();
// app.use('/late-quartet', async (req, res) => {
// const tokenPrices = await tokenService.getTokenPrices();

res.send({
bptPrice: tokenService.getPriceForToken(tokenPrices, '0xf3a602d30dcb723a74a0198313a7551feaca7dac'),
});
});
// res.send({
// bptPrice: tokenService.getPriceForToken(tokenPrices, '0xf3a602d30dcb723a74a0198313a7551feaca7dac'),
// });
// });
}
7 changes: 5 additions & 2 deletions modules/vebal/debug-voting-list.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,9 @@ it('Uses streamer-v1-map to find gauges (that use streamer instead of recipient)
const savedGauges = await repository.saveVotingGauges(fetchedVotingGauges);

expect(savedGauges).toMatchInlineSnapshot(`
[
{
"saveErrors": [],
"votingGaugesWithStakingGaugeId": [
{
"addedTimestamp": 1657479716,
"gaugeAddress": "0xcf5938ca6d9f19c73010c7493e19c02acfa8d24d",
Expand All @@ -315,6 +317,7 @@ it('Uses streamer-v1-map to find gauges (that use streamer instead of recipient)
"relativeWeightCap": undefined,
"stakingGaugeId": "0xfaad21203a7856889cb6eb644ab6864e7253107a",
},
]
],
}
`);
}, 1000_000);
40 changes: 22 additions & 18 deletions modules/vebal/vebal-voting-list.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,13 @@ export class VeBalVotingListService {
}

public async getValidVotingGauges() {
// A gauge should be included in the voting list when:
// - it is alive (not killed)
// - it is killed and has valid votes (the users should be able to reallocate votes)
const gaugesWithStaking = await prisma.prismaVotingGauge.findMany({
where: {
stakingGaugeId: { not: null },
OR: [{ status: 'ACTIVE' }, { relativeWeight: { not: '0' } }],
},
select: {
id: true,
Expand Down Expand Up @@ -137,13 +141,12 @@ export class VeBalVotingListService {

const syncErrors: Error[] = [];
for (const addressChunk of chunks) {
const { votingGauges, errors } = await this.fetchVotingGauges(addressChunk);
const { filteredGauges, errors } = await this.fetchVotingGauges(addressChunk);
syncErrors.push(...errors);

/*
We avoid saving gauges in specialVotingGaugeAddresses because they require special handling
*/
const cleanVotingGauges = votingGauges.filter(
const cleanVotingGauges = filteredGauges.filter(
(gauge) => !specialVotingGaugeAddresses.includes(gauge.gaugeAddress),
);

Expand All @@ -164,30 +167,31 @@ export class VeBalVotingListService {

const votingGauges = this.votingGauges.updateOnchainGaugesWithSubgraphData(onchainGauges, subgraphGauges);

try {
this.throwIfMissingVotingGaugeData(votingGauges);
} catch (error) {
errors.push(error as Error);
}
const gaugesWithMissingData = this.returnGaugesWithMissingData(votingGauges);

return { votingGauges, errors };
const filteredGauges = votingGauges.filter(
(gauge) => !gaugesWithMissingData.map((gauge) => gauge.gaugeAddress).includes(gauge.gaugeAddress),
);

if (gaugesWithMissingData.length > 0) {
const errorMessage =
'Detected active voting gauge/s with votes (relative weight > 0) that are not in subgraph: ' +
JSON.stringify(gaugesWithMissingData);
console.error(errorMessage);
errors.push(new Error(errorMessage));
}
return { filteredGauges, errors };
}

throwIfMissingVotingGaugeData(votingGauges: VotingGauge[]) {
returnGaugesWithMissingData(votingGauges: VotingGauge[]) {
const gaugesWithMissingData = votingGauges
.filter((gauge) => !veGauges.includes(gauge.gaugeAddress))
.filter((gauge) => !gauge.isInSubgraph)
.filter(this.votingGauges.isValidForVotingList)
.filter((gauge) => gauge.relativeWeight > 0)
// Ignore old Vebal gauge address
.filter((gauge) => gauge.gaugeAddress !== oldVeBalAddress);

if (gaugesWithMissingData.length > 0) {
const errorMessage =
'Detected active voting gauge/s with votes (relative weight > 0) that are not in subgraph: ' +
JSON.stringify(gaugesWithMissingData);
console.error(errorMessage);
throw new Error(errorMessage);
}
return gaugesWithMissingData;
}
}

Expand Down
11 changes: 3 additions & 8 deletions modules/vebal/voting-gauges.repository.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,19 +116,14 @@ it('successfully saves onchain gauges', async () => {
describe('When staking gauge is not found ', () => {
beforeEach(() => prismaMock.prismaPoolStakingGauge.findFirst.mockResolvedValue(null));

it('throws when gauge is valid for voting (not killed)', async () => {
it('has errors when gauge is valid for voting (not killed)', async () => {
const repository = new VotingGaugesRepository(prismaMock);

const votingGauge = aVotingGauge({ network: Chain.MAINNET, isKilled: false });

let error: Error = EmptyError;
try {
await repository.saveVotingGauges([votingGauge]);
} catch (e) {
error = e as Error;
}
const { votingGaugesWithStakingGaugeId, saveErrors } = await repository.saveVotingGauges([votingGauge]);

expect(error.message).toContain('VotingGauge not found in PrismaPoolStakingGauge:');
expect(saveErrors.length).toBe(1);
});

it('does not throw when gauge is valid for voting (killed with no votes)', async () => {
Expand Down
1 change: 0 additions & 1 deletion modules/vebal/voting-gauges.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,6 @@ export class VotingGaugesRepository {
}

async saveVotingGauge(gauge: VotingGauge) {
if (!this.isValidForVotingList(gauge)) return;
try {
const upsertFields = {
id: gauge.gaugeAddress,
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
"node-cron": "^3.0.0",
"prisma": "^4.1.1",
"safe-compare": "^1.1.4",
"stellate": "^1.15.2",
"stellate": "2.7.1",
"ts-dotenv": "^0.8.1",
"uuid": "^8.3.2",
"yarn": "^1.22.19"
Expand Down
Loading

0 comments on commit e6ed07d

Please sign in to comment.