iotaledger / iri

IOTA Reference Implementation
Other
1.15k stars 370 forks source link

Implement spam protection #1293

Open ghost opened 5 years ago

ghost commented 5 years ago

Description

Implement spam protection as suggested by Come-from-Beyond:

[12:37] Come-from-Beyond: if you don't relay txs from top 33% spammers then spam eventually dies [17:58] Come-from-Beyond: dropping 33% of most spammy neighbors [17:58] Come-from-Beyond: or rather not sharing their txs with the others [17:58] Come-from-Beyond: 120 min work for a lazy coder

Solution: [11:06] Come-from-Beyond: Take all new txs received from the neighbors during last 5 sec and count them. Sort the neighbors according to that count from lowest to highest count. For the next 5 sec don't share new txs received from 33% neighbors with highest count. [11:07] Come-from-Beyond: We also need solution for limiting number of new txs pushed thru API calls [11:07] Come-from-Beyond: Set limit per IP for broadcastTx (and other appropriate functions)

Motivation

Network has a hard time handling high TPS. Nodes getting out-of-sync, CTPS rate (%) drops (also for value tx). ZMQ streams give incorrect data.

[18:11] Come-from-Beyond: current txs are not confirmed because source of txs is far from the Coo [18:11] lunfardo: how to determine a spammy neigbor? [18:11] Come-from-Beyond: few missing txs is enough to invalidate million other txs [18:11] Come-from-Beyond: that neighbor will be sending most of new txs

Requirements

Implemented spam protection in IRI.

Open Questions (optional)

Am I planning to do it myself with a PR?

No.

Bounty for now: 0.1 btc, for more info check #tanglespam in Discord.

Johnny-Milkshakes commented 5 years ago

Intuitively speaking I would think if implemented there should be a minimum threshold before the limiter kicks in. Either % based or a hard coded tps at which point it starts the spam prevention. I am not entirely convinced of the effectiveness of this approach though

ghost commented 5 years ago

How do you determine that threshold? Number of tps that a regular node can handle before it get's out of sync?

ghost commented 5 years ago

If anyone wants to test, i've setup an approach with my rusty Java skills:

https://github.com/nstrat/iri/commit/c583d4455c1408378f2f716a77e677f564babc02

georgmittendorfer commented 5 years ago

@nstrat I gave it a try, too. Took your commit as an inspiration. See PR.

Should the 33% (34%) be calculated from only the nodes that are sending txs within the time interval or from all neighbors? I guess only from the sending nodes, right? So if only two nodes are active no node gets blocked for broadcasting.

This is the branch that patches the current master (version 1.6.0): https://github.com/georgmittendorfer/iri/tree/feature-spam-prevention

Patched version if someone wants to download it: https://github.com/georgmittendorfer/iri/releases

georgmittendorfer commented 5 years ago

Question with regard to 33% calculation. There are several options:

Drop percentage could be calculated on every broadcast check randomly (e.g. 4 neighbors: tx off 2nd most active get's not broadcasted with 33% chance). Downside: calculation would be more costly performance wise.

What do you think is the best solution?

ghost commented 5 years ago

Good job. I thought option 1, but maybe CfB meant option 2.

georgmittendorfer commented 5 years ago
microhash [IF] Today at 1:26 PM
@Come-from-Beyond Regarding the 33% spam protection, should that be 1 or 2 neighbors in case a node has 4 or 5 neighbors. So ceil(), floor() or round()?

Come-from-Beyond Today at 1:31 PM
ceil

I read that this way:

Unclear what to do with two neighbors. We block one for now.