Skip to content

Commit e2d0ad5

Browse files
committed
indexer-service: Rate limit express server
1 parent 4425576 commit e2d0ad5

File tree

3 files changed

+1195
-840
lines changed

3 files changed

+1195
-840
lines changed

packages/indexer-service/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
"evt": "1.9.12",
4343
"express": "4.17.1",
4444
"express-graphql": "0.9.0",
45+
"express-rate-limit": "^5.5.1",
4546
"graphql": "15.4.0",
4647
"graphql-tag": "2.11.0",
4748
"graphql-tools": "5.0.0",
@@ -59,6 +60,7 @@
5960
"@types/bs58": "4.0.1",
6061
"@types/cors": "2.8.8",
6162
"@types/express": "4.17.8",
63+
"@types/express-rate-limit": "^5.1.3",
6264
"@types/isomorphic-fetch": "0.0.35",
6365
"@types/jest": "26.0.15",
6466
"@types/morgan": "1.9.2",

packages/indexer-service/src/server/index.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
} from '@graphprotocol/indexer-common'
2020
import { createCostServer } from './cost'
2121
import { createOperatorServer } from './operator'
22+
import rateLimit from 'express-rate-limit'
2223

2324
export interface ServerOptions {
2425
logger: Logger
@@ -139,6 +140,18 @@ export const createApp = async ({
139140

140141
const app = express()
141142

143+
// Limit status requests to 9000/30min (5/s)
144+
const slowLimiter = rateLimit({
145+
windowMs: 30 * 60 * 1000, // 1 minutes
146+
max: 9000,
147+
})
148+
149+
// Limit network requests to 90000/30min (50/s)
150+
const networkLimiter = rateLimit({
151+
windowMs: 30 * 60 * 1000, // 1 minutes
152+
max: 90000,
153+
})
154+
142155
// Log requests to the logger stream
143156
// eslint-disable-next-line @typescript-eslint/no-explicit-any
144157
app.use(morgan('tiny', { stream: loggerStream }) as any)
@@ -160,20 +173,23 @@ export const createApp = async ({
160173
// Endpoint for the public status API
161174
app.use(
162175
'/status',
176+
networkLimiter,
163177
bodyParser.json(),
164178
await createStatusServer({ graphNodeStatusEndpoint }),
165179
)
166180

167181
// Endpoint for the public cost API
168182
app.use(
169183
'/cost',
184+
slowLimiter,
170185
bodyParser.json(),
171186
await createCostServer({ indexerManagementClient, metrics }),
172187
)
173188

174189
// Endpoint for operator information
175190
app.use(
176191
'/operator',
192+
slowLimiter,
177193
bodyParser.json(),
178194
await createOperatorServer({ operatorPublicKey }),
179195
)
@@ -187,6 +203,7 @@ export const createApp = async ({
187203
// Endpoint for network subgraph queries
188204
app.post(
189205
`/network`,
206+
networkLimiter,
190207
bodyParser.raw({ type: 'application/json' }),
191208
async (req, res) => {
192209
try {

0 commit comments

Comments
 (0)