Skip to content

Commit

Permalink
add limit for slot range and pools
Browse files Browse the repository at this point in the history
  • Loading branch information
ecioppettini committed Nov 28, 2023
1 parent dc5338b commit d474564
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 29 deletions.
80 changes: 51 additions & 29 deletions webserver/server/app/controllers/DelegationForPoolController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,44 +2,66 @@ import { Body, Controller, TsoaResponse, Res, Post, Route, SuccessResponse } fro
import { StatusCodes } from 'http-status-codes';
import tx from 'pg-tx';
import pool from '../services/PgPoolSingleton';
import type { ErrorShape } from '../../../shared/errors';
import { genErrorMessage, type ErrorShape, Errors } from '../../../shared/errors';
import type { EndpointTypes } from '../../../shared/routes';
import { Routes } from '../../../shared/routes';
import { delegationsForPool } from '../services/DelegationForPool';
import { DelegationForPoolResponse } from '../../../shared/models/DelegationForPool';
import { POOL_DELEGATION_LIMIT } from '../../../shared/constants';

const route = Routes.delegationForPool;

@Route('delegation/pool')
export class DelegationForPoolController extends Controller {
@SuccessResponse(`${StatusCodes.OK}`)
@Post()
public async delegationForPool(
@Body()
requestBody: EndpointTypes[typeof route]['input'],
@Res()
errorResponse: TsoaResponse<
StatusCodes.BAD_REQUEST | StatusCodes.CONFLICT | StatusCodes.UNPROCESSABLE_ENTITY,
ErrorShape
>
): Promise<EndpointTypes[typeof route]['response']> {
const response = await tx<
DelegationForPoolResponse
>(pool, async dbTx => {
const data = await delegationsForPool({
pools: requestBody.pools.map(poolId => Buffer.from(poolId, 'hex')),
range: requestBody.range,
dbTx
});

return data.map(data => ({
credential: data.credential as string,
pool: data.pool,
txId: data.tx_id as string,
slot: data.slot,
}));
});
@SuccessResponse(`${StatusCodes.OK}`)
@Post()
public async delegationForPool(
@Body()
requestBody: EndpointTypes[typeof route]['input'],
@Res()
errorResponse: TsoaResponse<
StatusCodes.BAD_REQUEST | StatusCodes.CONFLICT | StatusCodes.UNPROCESSABLE_ENTITY,
ErrorShape
>
): Promise<EndpointTypes[typeof route]['response']> {
if (requestBody.pools.length > POOL_DELEGATION_LIMIT.POOLS) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
return errorResponse(
StatusCodes.BAD_REQUEST,
genErrorMessage(Errors.PoolsLimitExceeded, {
limit: POOL_DELEGATION_LIMIT.POOLS,
found: requestBody.pools.length,
})
);
}

return response;
const slotRangeSize = requestBody.range.maxSlot - requestBody.range.minSlot;
if (slotRangeSize > POOL_DELEGATION_LIMIT.SLOT_RANGE) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
return errorResponse(
StatusCodes.BAD_REQUEST,
genErrorMessage(Errors.SlotRangeLimitExceeded, {
limit: POOL_DELEGATION_LIMIT.SLOT_RANGE,
found: slotRangeSize,
})
);
}

const response = await tx<DelegationForPoolResponse>(pool, async dbTx => {
const data = await delegationsForPool({
pools: requestBody.pools.map(poolId => Buffer.from(poolId, 'hex')),
range: requestBody.range,
dbTx,
});

return data.map(data => ({
credential: data.credential as string,
pool: data.pool,
txId: data.tx_id as string,
slot: data.slot,
}));
});

return response;
}
}
5 changes: 5 additions & 0 deletions webserver/shared/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,8 @@ export const DEX_PRICE_LIMIT = {
REQUEST_ASSET_PAIRS: 100,
RESPONSE: 1000,
};

export const POOL_DELEGATION_LIMIT = {
POOLS: 50,
SLOT_RANGE: 200,
};
14 changes: 14 additions & 0 deletions webserver/shared/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ export enum ErrorCodes {
AssetLimitExceeded = 8,
CredentialLimitExceeded = 9,
AssetPairLimitExceeded = 10,
PoolsLimitExceeded = 11,
SlotRangeLimitExceeded = 12,
}

export type ErrorShape = {
Expand Down Expand Up @@ -86,6 +88,18 @@ export const Errors = {
detailsGen: (details: { limit: number; found: number }) =>
`Limit of ${details.limit}, found ${details.found}`,
},
PoolsLimitExceeded: {
code: ErrorCodes.PoolsLimitExceeded,
prefix: "Exceeded request pools limit.",
detailsGen: (details: { limit: number; found: number }) =>
`Limit of ${details.limit}, found ${details.found}`,
},
SlotRangeLimitExceeded: {
code: ErrorCodes.SlotRangeLimitExceeded,
prefix: "Exceeded request slot range limit.",
detailsGen: (details: { limit: number; found: number }) =>
`Limit of ${details.limit}, found ${details.found}`,
},
} as const;

export function genErrorMessage<T extends typeof Errors[keyof typeof Errors]>(
Expand Down

0 comments on commit d474564

Please sign in to comment.