Feat/address rate limiting#409
Merged
Merged
Conversation
…list, config, cleanup
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
rate-limit.js
AddressRateLimiter class — same sliding window algorithm as RateLimiter, keyed by Stacks address (case-insensitive). Whitelisted addresses bypass all checks. Methods: isAllowed, getRemaining, isWhitelisted, addToWhitelist, removeFromWhitelist, getWhitelist, updateConfig, getConfig, cleanup
parseAddressWhitelist(value) — parses a comma-separated env var string into an address array
validateAddressRateLimitConfig(maxRequests, windowMs) — delegates to the existing validateRateLimitConfig since the same bounds apply
server.js
Three new env vars read at startup: ADDRESS_RATE_LIMIT_MAX_REQUESTS (default 50), ADDRESS_RATE_LIMIT_WINDOW_MS (default 60000), ADDRESS_RATE_LIMIT_WHITELIST (default empty)
addressRateLimiter instance created alongside rateLimiter
getAddressRateLimiter() getter exported
Chainhook events handler: after IP check passes, each parsed tip event's sender is checked against addressRateLimiter — returns 429 with address and remaining in the error context if exceeded
addressRateLimiter.cleanup() added to the 60-second cleanup interval
Four new admin endpoints: GET /api/admin/address-rate-limit, POST /api/admin/address-rate-limit, GET /api/admin/address-rate-limit/whitelist, POST /api/admin/address-rate-limit/whitelist, DELETE /api/admin/address-rate-limit/whitelist — all auth-gated the same way as the existing IP rate limit endpoints
Startup log includes address_rate_limit and address_whitelist_size
Closes #387