I have a WIP branch where I implemented a fairly simple DDoS protector for lespay UDP talk requests (400 LOC total + utils.WeightedRandomSelect, does not use the NodeStateMachine). The reason I spent time with it at this early stage is that I think the token market interface really needs to be designed with this aspect in mind. Polling rates and unhealthy competition (arms race) can be a problem with markets, especially in a decentralized and uncontrolled, somewhat chaotic environment. The reason I opened an issue for discussion about it is because I think something like this could be a recommendation (maybe even an EIP) for our entire DHT and I am interested in your opinons from both a security and DHT centric perspective.
So basically what it does is
keeps request queues by both IP address (string) and enode.ID
has a single processing loop that even does time.Sleeps between serving them so that the DHT logic can never hurt other processes
has a probabilistic selection based throttling mechanism (which behaves trivially and deterministically when there is no extreme usage but tries to give a sufficient chance to the proven useful connections during extreme traffic).
50% of serving probability weights are distributed equally between active individual IP addresses. Multiple enode.IDs can request from the same IP in which case the IP's weight is further distributed equally.
the other 50% is proportional to value / sumValue where the "value" is anything that is an indicator of usefulness in the (preferably not very distant) past.
the first half protects from DoS but gives limited protection againgst DDoS, the second one ensures that already proven connections can not be easily broken even with heavy DDoS so there is much less incentive to even try and spend money on. Basically an attacker can only hinder the forming of new connections but that will not do real damage very soon. This is also a Kademlia recommendation to prioritize older contiuous connections. Maybe for a Kademlia the weight could simply be the connection age. For lespay it is money received from the enode.ID. Multiple dimensions of value can also be easily added if necessary, each dimension getting a guaranteed total percentage of service.
The service throttling can also take actual serving resource costs (CPU and/or bandwidth usually) into account. An attack deliberately making the most expensive requests will be proportionally more heavily throttled while economical usage of the resources of the serving node is rewarded by quicker responses. Practice with LES servers has shown though that direct time-based cost metering sometimes gives extreme outliers that are unrelated to the given request. utils.CostFilter ensures that these outliers will not block service for some nodes by accident.
I have a WIP branch where I implemented a fairly simple DDoS protector for lespay UDP talk requests (400 LOC total + utils.WeightedRandomSelect, does not use the NodeStateMachine). The reason I spent time with it at this early stage is that I think the token market interface really needs to be designed with this aspect in mind. Polling rates and unhealthy competition (arms race) can be a problem with markets, especially in a decentralized and uncontrolled, somewhat chaotic environment. The reason I opened an issue for discussion about it is because I think something like this could be a recommendation (maybe even an EIP) for our entire DHT and I am interested in your opinons from both a security and DHT centric perspective. So basically what it does is
string
) andenode.ID
time.Sleep
s between serving them so that the DHT logic can never hurt other processesenode.ID
s can request from the same IP in which case the IP's weight is further distributed equally.value / sumValue
where the "value" is anything that is an indicator of usefulness in the (preferably not very distant) past.enode.ID
. Multiple dimensions of value can also be easily added if necessary, each dimension getting a guaranteed total percentage of service.https://github.com/zsfelfoldi/go-ethereum/blob/les4udp/les/utils/limiter.go
The service throttling can also take actual serving resource costs (CPU and/or bandwidth usually) into account. An attack deliberately making the most expensive requests will be proportionally more heavily throttled while economical usage of the resources of the serving node is rewarded by quicker responses. Practice with LES servers has shown though that direct time-based cost metering sometimes gives extreme outliers that are unrelated to the given request.
utils.CostFilter
ensures that these outliers will not block service for some nodes by accident.https://github.com/zsfelfoldi/go-ethereum/blob/les4udp/les/utils/costfilter.go