Skip to content
This repository has been archived by the owner on Jun 11, 2024. It is now read-only.

Rate limit WebSocket messages - Closes #3975 #3981

Merged
merged 13 commits into from
Jul 31, 2019

Conversation

jondubois
Copy link
Contributor

@jondubois jondubois commented Jul 18, 2019

What was the problem?

There was no rate limiting at the WebSocket level to block malicious peers.

How did I fix it?

  • Track the raw WebSocket message rate. If a peer tries to send more than wsMaxMessageRate messages per second, they will be disconnected with a forbidden message.
  • Adjusted how the p2p request and p2p message rate is calculated to be consistent with the calculation of the wsMaxMessageRate and to increase precision.

How to test it?

New integration test cases were added.

npm run test:integration

Review checklist

Copy link
Contributor

@ishantiw ishantiw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we are going to disconnect from a peer after it reaches the threshold of the number of messages it sends per second, in theory, it should also be moved from tried to new peer or follow the eviction rules on disconnection, do you think it will have any impact on the LIP?
Because this is partly handled in banning,

getTransactions: More than 3 requests in a 10 s time window : Honest peers should send a getTransactions message only after receiving a new postTransactionsAnnouncement message and in particular only request transactions every 5 seconds

Similar ban scores for postTransactionsAnnouncement, postSignatures, etc. My concern is, this is working in parallel to Banning and a peer is only punished when it reaches a ban score and disconnected for 24 hours. Otherwise, a peer can get evicted very quickly from newPeers list because of double punishment from two mechanisms (rateLimit and Banning).

Apart from this, it looks good.

@@ -151,16 +155,23 @@ export class Peer extends EventEmitter {
responseRate: number;
lastResponded: number;
};
private _callCounter: Map<string, number>;
private _rpcCounter: Map<string, number>;
private _rpcRates: Map<any, number>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why we have any type as key?

[...this._rpcCounter.entries()].map(entry => {
const rate = entry[1] / this._rateInterval;

return [entry[0], rate] as any;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't entry[0] is string type and we can use it as key for rpcRates type as Map<string, number>?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't need to typecast as any, it doesn't give me warning

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It gives me warnings in vscode if I don't put any.

Copy link
Contributor

@ishantiw ishantiw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The solution in general looks good, just a few comments related to TS

}

this._rpcRates = new Map(
[...this._rpcCounter.entries()].map(entry => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe for clarity we can use .map([key, rate]) => or .map([key, value]) =>?

this._rpcCounter = new Map();

this._messageRates = new Map(
[...this._messageCounter.entries()].map(entry => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

[...this._rpcCounter.entries()].map(entry => {
const rate = entry[1] / this._rateInterval;

return [entry[0], rate] as any;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't need to typecast as any, it doesn't give me warning

Copy link
Contributor

@mitsuaki-u mitsuaki-u left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Besides @ishantiw requested changes LGTM

@jondubois jondubois merged commit 003e2bd into feature/implement-lip-p2p Jul 31, 2019
@shuse2 shuse2 deleted the 3975-rate_limit branch August 2, 2019 10:06
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants