-
Notifications
You must be signed in to change notification settings - Fork 7
Client Side Flow Control model for the LES protocol
Any node which takes on a server role inside the LES protocol needs to be able to somehow limit the amount of work it does for each client peer during a given time period. They can always just serve requests slowly if they are overloaded, but it would definitely be beneficial to give some sort of flow control feedback to the clients. This way, clients could (and would have incentive to) behave nicely and not send requests too quickly in the first place (and then possibly timeout and resend while the server is still working on them). They could also distribute requests better between multiple servers they are connected to. And if clients can do this, servers can expect them to do this and drop them instantly if they break the flow control rules.
Let us assume that serving each request has a cost (depending on type and parameters) for the server. This cost is determined by the server, but it has an upper limit for any valid request. The server assigns a "buffer" for each client from which the cost of each request is deduced. The buffer has an upper limit and a recharge rate (cost per second). The server can decide to recharge it more quickly at any time if it has more free resources, but there is a guaranteed minimum recharge rate. If a request is received that would drain the client's buffer below zero, the client broke the flow control rules and it is instantly dropped.
The server announces three values during handshake:
- Buffer Limit (BL)
- Maximum Request Cost (MRC)
- Minimum Rate of Recharge (MRR)
It sets the Buffer Value (BV) of the client to BL. If a request is received from a client, it calculates the cost according to its own estimates (but not higher than MRC), then decudes it from BV. If BV goes negative, drops the peer, otherwise starts serving the request. The reply message contains the current BV (possibly higher than the value calculated when receiving the request, since BV is constantly recharged). Note that since the server can always determine any cost up to MRC for a request (and a client should not assume otherwise), it can drop a client without even processing the message and calculating its cost if it receives one while BV < MRC because that's already a protocol breach.
The client always has a lowest estimate for its current BV, called BLE. It
- sets BLE to BL at handshake
- doesn't send any request to the server when BLE < MRC
- deduces MRC when sending a request
- recharges BLE at the rate of MRR when less than BL
- updates it with the BV value when it receives a reply message