[ETCM-331] Add Rate Limit for rpc requests#806
Conversation
|
|
||
| override def route: Route = cors(corsSettings) { | ||
| (pathEndOrSingleSlash & post) { | ||
| (extractClientIP & entity(as[JsonRpcRequest])) { (clientAddress: RemoteAddress, request: JsonRpcRequest) => |
There was a problem hiding this comment.
Is it enough to check IP address only in HTTP header, or maybe we shouldn't trust them?
Maybe we have to read AttributeKeys.remoteAddress? What do you think?
There was a problem hiding this comment.
HI! Thanks for the comment! I think you're right. I'll create a different task for it (since it might escape the scope of this one -> just bringing back old behavior)
…-331-mantis-protection
799f20c to
0877ceb
Compare
|
|
||
| val latestTimestampCacheSize: Int | ||
|
|
||
| val latestRequestTimestamps: LruMap[RemoteAddress, Long] |
There was a problem hiding this comment.
Maybe this is included in the above comment by Maxi, but also this can be derived from the config here without having to override it on it's sons
| } | ||
|
|
||
| def handleRequest(clientAddress: RemoteAddress, request: JsonRpcRequest): StandardRoute = { | ||
| if (ipTrackingEnabled && request.method != FaucetJsonRpcController.Status) { |
There was a problem hiding this comment.
Why are we only disabling this for the faucet status? Maybe it's because it's used as the healthcheck? I though the healthcheck was something separately
There was a problem hiding this comment.
I added a FIXME for this, the faucet Status should somehow work as a healthcheck so I left it out of the rate limiting in case it's being used by some of our services. Eventually it should be part of the healthcheck or be handled more elegantly
| status shouldEqual StatusCodes.TooManyRequests | ||
| } | ||
|
|
||
| FakeClock.advanceTime(10) |
There was a problem hiding this comment.
Minor: maybe we should set this to 2* config.minRequestInterval instead of the hardcoded 10?
| } | ||
| } | ||
|
|
||
| object FakeClock extends Clock { |
There was a problem hiding this comment.
Maybe this should be a class FakeClock extends Clock and on the TestSetup we create an instance of it instead of using this singleton?
16cd9d5 to
ac6f7e7
Compare
ac6f7e7 to
341db30
Compare
053890d to
6e82731
Compare
…-331-mantis-protection
ntallar
left a comment
There was a problem hiding this comment.
Only a minor comment apart from which LGTM! I played around with it and it worked as expected!
.\\ //.
. \ \ / /.
.\ ,\ /` /,.-
-. \ /'/ / .
` - `-' \ -
'. /.\`
- .-
:`//.'
.`.'
.' BP
| val timeMillis = clock.instant().toEpochMilli | ||
| val latestRequestTimestamp = latestRequestTimestamps.getOrElse(clientAddress, 0L) | ||
|
|
||
| val response = latestRequestTimestamp + config.rateLimit.minRequestInterval.toMillis < timeMillis |
There was a problem hiding this comment.
Minor: maybe we should rename it: isBelowRateLimit?
…-331-mantis-protection
Description
In a previous refactor, IP limit tracking was removed due to the nature of the refactor and because this isn't a problem that mantis codebase should be handling. As a temporary solution, this PR brings back the IP limit tracking for
faucet_sendFundsrequests.Proposed Solution
First approach [Deprecated]
Two new traits extending the
JsonRpcHttpServerwere created to separate the behavior for the node and the faucetFaucetJsonRpcHttpServerNodeJsonRpcHttpServerTheir child classes (
BasicJsonRpcHttpServerandJsonRpcHttpsServer) also need to be extended for the node and for the faucet. The main goal is being able to handle therouteval and extract the Ip and limit the requests by ip, but only for the faucet.Final Approach
Add ip limit tracking as a JsonRpc capability. It can be enabled/disabled by configuration.
Some decisions to take into consideration:
Testing
Run the faucet with a node and try to execute requests in less than the minimum time interval allowed between requests (10 seconds by default). Also, verify that
faucet_statushas no requests limit and should not affect thefaucet_sendFundsrequests.