-
Notifications
You must be signed in to change notification settings - Fork 75
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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)
src/main/scala/io/iohk/ethereum/jsonrpc/server/http/FaucetJsonRpcHttpServer.scala
Outdated
Show resolved
Hide resolved
src/main/scala/io/iohk/ethereum/jsonrpc/server/http/BasicJsonRpcHttpServer.scala
Outdated
Show resolved
Hide resolved
src/main/scala/io/iohk/ethereum/jsonrpc/server/http/FaucetJsonRpcHttpServer.scala
Outdated
Show resolved
Hide resolved
src/main/scala/io/iohk/ethereum/jsonrpc/server/http/FaucetJsonRpcHttpServer.scala
Outdated
Show resolved
Hide resolved
src/main/scala/io/iohk/ethereum/jsonrpc/server/http/NodeJsonRpcHttpServer.scala
Outdated
Show resolved
Hide resolved
src/main/scala/io/iohk/ethereum/jsonrpc/server/http/NodeJsonRpcHttpServer.scala
Outdated
Show resolved
Hide resolved
src/main/scala/io/iohk/ethereum/jsonrpc/server/http/FaucetJsonRpcHttpServer.scala
Outdated
Show resolved
Hide resolved
…-331-mantis-protection
799f20c
to
0877ceb
Compare
src/main/scala/io/iohk/ethereum/jsonrpc/server/http/JsonRpcHttpServer.scala
Outdated
Show resolved
Hide resolved
src/main/scala/io/iohk/ethereum/jsonrpc/server/http/InsecureJsonRpcHttpServer.scala
Outdated
Show resolved
Hide resolved
src/main/scala/io/iohk/ethereum/jsonrpc/server/http/SecureJsonRpcHttpServer.scala
Outdated
Show resolved
Hide resolved
src/main/scala/io/iohk/ethereum/jsonrpc/server/http/JsonRpcHttpServer.scala
Outdated
Show resolved
Hide resolved
src/main/scala/io/iohk/ethereum/jsonrpc/server/http/JsonRpcHttpServer.scala
Outdated
Show resolved
Hide resolved
src/main/scala/io/iohk/ethereum/jsonrpc/server/http/InsecureJsonRpcHttpServer.scala
Show resolved
Hide resolved
|
||
val latestTimestampCacheSize: Int | ||
|
||
val latestRequestTimestamps: LruMap[RemoteAddress, Long] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
} ~ entity(as[Seq[JsonRpcRequest]]) { request => | ||
handleBatchRequest(request) | ||
} | ||
} | ||
} | ||
|
||
def handleRequest(clientAddress: RemoteAddress, request: JsonRpcRequest): StandardRoute = { | ||
if (ipTrackingEnabled && request.method != FaucetJsonRpcController.Status) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
src/main/scala/io/iohk/ethereum/jsonrpc/server/http/JsonRpcHttpServer.scala
Outdated
Show resolved
Hide resolved
ac6f7e7
to
341db30
Compare
src/main/scala/io/iohk/ethereum/jsonrpc/server/http/RateLimit.scala
Outdated
Show resolved
Hide resolved
src/main/scala/io/iohk/ethereum/jsonrpc/server/http/SecureJsonRpcHttpServer.scala
Outdated
Show resolved
Hide resolved
src/test/scala/io/iohk/ethereum/jsonrpc/server/http/JsonRpcHttpServerSpec.scala
Show resolved
Hide resolved
src/test/scala/io/iohk/ethereum/jsonrpc/server/http/JsonRpcHttpServerSpec.scala
Show resolved
Hide resolved
053890d
to
6e82731
Compare
…-331-mantis-protection
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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_sendFunds
requests.Proposed Solution
First approach [Deprecated]
Two new traits extending the
JsonRpcHttpServer
were created to separate the behavior for the node and the faucetFaucetJsonRpcHttpServer
NodeJsonRpcHttpServer
Their child classes (
BasicJsonRpcHttpServer
andJsonRpcHttpsServer
) also need to be extended for the node and for the faucet. The main goal is being able to handle theroute
val 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_status
has no requests limit and should not affect thefaucet_sendFunds
requests.