Bitcoin core recently merged a change that replaces its previous per peer transaction relay rate limiting with a global approach. Previously, it maintained a separate queue of transaction announcements for each peer which were continuously sorted by transaction priority, each peer had a relay limit of about 7 transactions per second which works fine normally, but then a sudden burst of transactions could make the queue grow faster than they could drain and since the queues were repeatedly sorted as new transactions arrives, this could potentially result in excess use of CPU and become a DoS vector.
The new approach uses global token buckets based on:
- transaction count
- serialized transaction size
If the capacity is not enough then the transactions are placed into a
global backlog which prevents independent queues from growing without the same global control, then transactions are selected in accordance to their priority and then placed into small per peer queues for relay.
What’s interesting is that this didn’t simply put a smaller limit on the old queues but also changed how the node manages it overall relay resources. It also shows that DoS protection isn’t always about rejecting malicoius or invalid data, but even legitimate looking network activity can become a problem if a node is forced to spend too many resources processing it.