Move bytes rate limits to a different rlp key

This commit is contained in:
Andrea Maria Piana 2020-06-09 09:21:13 +02:00
parent c5577418b7
commit 35e95d1568
8 changed files with 72 additions and 38 deletions

View File

@ -66,8 +66,10 @@ type WakuHost interface {
LightClientModeConnectionRestricted() bool
// ConfirmationsEnabled returns true if message confirmations are enabled.
ConfirmationsEnabled() bool
// RateLimits returns the current rate limits for the host
RateLimits() RateLimits
// PacketRateLimits returns the current rate limits for the host
PacketRateLimits() RateLimits
// BytesRateLimits returns the current rate limits for the host
BytesRateLimits() RateLimits
// MinPow returns the MinPow for the host
MinPow() float64
// BloomFilterMode returns whether the host is using bloom filter

View File

@ -62,15 +62,12 @@ func (MetricsRateLimiterHandler) ExceedIPLimit() error {
}
// RateLimits contains information about rate limit settings.
// It is exchanged using rateLimitingCode packet or in the handshake.
// It's agnostic on what it's being rate limited on (bytes or number of packets currently)
// It's exchanged with the status-update packet code
type RateLimits struct {
PacketIPLimits uint64 // packets per second from a single IP (default 0, no limits)
PacketPeerIDLimits uint64 // packets per second from a single peer ID (default 0, no limits)
PacketTopicLimits uint64 // packets per second from a single topic (default 0, no limits)
BytesIPLimits uint64 // bytes per second from a single IP (default 0, no limits)
BytesPeerIDLimits uint64 // bytes per second from a single peer ID (default 0, no limits)
BytesTopicLimits uint64 // bytes per second from a single topic (default 0, no limits)
IPLimits uint64 // amount per second from a single IP (default 0, no limits)
PeerIDLimits uint64 // amount per second from a single peer ID (default 0, no limits)
TopicLimits uint64 // amount per second from a single topic (default 0, no limits)
}
func (r RateLimits) IsZero() bool {
@ -125,10 +122,10 @@ var defaultPeerRateLimiterConfig = PeerRateLimiterConfig{
// PeerRateLimiter represents a rate limiter that limits communication between Peers
type PeerRateLimiter struct {
packetPeerIDThrottler *tb.Throttler
packetIpThrottler *tb.Throttler
packetIPThrottler *tb.Throttler
bytesPeerIDThrottler *tb.Throttler
bytesIpThrottler *tb.Throttler
bytesIPThrottler *tb.Throttler
PacketLimitPerSecIP int64
PacketLimitPerSecPeerID int64
@ -150,9 +147,9 @@ func NewPeerRateLimiter(cfg *PeerRateLimiterConfig, handlers ...RateLimiterHandl
return &PeerRateLimiter{
packetPeerIDThrottler: tb.NewThrottler(time.Millisecond * 100),
packetIpThrottler: tb.NewThrottler(time.Millisecond * 100),
packetIPThrottler: tb.NewThrottler(time.Millisecond * 100),
bytesPeerIDThrottler: tb.NewThrottler(time.Millisecond * 100),
bytesIpThrottler: tb.NewThrottler(time.Millisecond * 100),
bytesIPThrottler: tb.NewThrottler(time.Millisecond * 100),
PacketLimitPerSecIP: cfg.PacketLimitPerSecIP,
PacketLimitPerSecPeerID: cfg.PacketLimitPerSecPeerID,
BytesLimitPerSecIP: cfg.BytesLimitPerSecIP,
@ -256,10 +253,10 @@ func (r *PeerRateLimiter) throttleIP(ip string, size uint32) bool {
var bytesLimiterResponse bool
if r.PacketLimitPerSecIP != 0 {
packetLimiterResponse = r.packetIpThrottler.Halt(ip, 1, r.PacketLimitPerSecIP)
packetLimiterResponse = r.packetIPThrottler.Halt(ip, 1, r.PacketLimitPerSecIP)
}
if r.BytesLimitPerSecIP != 0 {
bytesLimiterResponse = r.bytesIpThrottler.Halt(ip, int64(size), r.BytesLimitPerSecIP)
bytesLimiterResponse = r.bytesIPThrottler.Halt(ip, int64(size), r.BytesLimitPerSecIP)
}
return packetLimiterResponse || bytesLimiterResponse

View File

@ -135,7 +135,7 @@ func TestPeerBytesLimiterHandler(t *testing.T) {
msg, err := rw1.ReadMsg()
require.NoError(t, err)
require.EqualValues(t, 101, msg.Code)
msg.Discard()
require.NoError(t, msg.Discard())
}
close(done)
}()

View File

@ -40,7 +40,7 @@ type StatusOptions struct {
func StatusOptionsFromHost(host common.WakuHost) StatusOptions {
opts := StatusOptions{}
rateLimits := host.RateLimits()
rateLimits := host.PacketRateLimits()
opts.RateLimits = &rateLimits
lightNode := host.LightClientMode()

View File

@ -48,8 +48,10 @@ type Peer struct {
// In that case no envelope is accepted.
fullNode bool
confirmationsEnabled bool
rateLimitsMu sync.Mutex
rateLimits common.RateLimits
packetRateLimitsMu sync.Mutex
packetRateLimits common.RateLimits
bytesRateLimitsMu sync.Mutex
bytesRateLimits common.RateLimits
known mapset.Set // Messages already known by the peer to avoid wasting bandwidth
}
@ -488,8 +490,11 @@ func (p *Peer) setOptions(peerOptions StatusOptions) error {
if peerOptions.ConfirmationsEnabled != nil {
p.confirmationsEnabled = *peerOptions.ConfirmationsEnabled
}
if peerOptions.RateLimits != nil {
p.setRateLimits(*peerOptions.RateLimits)
if peerOptions.PacketRateLimits != nil {
p.setPacketRateLimits(*peerOptions.PacketRateLimits)
}
if peerOptions.BytesRateLimits != nil {
p.setBytesRateLimits(*peerOptions.BytesRateLimits)
}
return nil
@ -591,10 +596,16 @@ func (p *Peer) setTopicInterest(topicInterest []common.TopicType) {
p.bloomFilter = nil
}
func (p *Peer) setRateLimits(r common.RateLimits) {
p.rateLimitsMu.Lock()
p.rateLimits = r
p.rateLimitsMu.Unlock()
func (p *Peer) setPacketRateLimits(r common.RateLimits) {
p.packetRateLimitsMu.Lock()
p.packetRateLimits = r
p.packetRateLimitsMu.Unlock()
}
func (p *Peer) setBytesRateLimits(r common.RateLimits) {
p.bytesRateLimitsMu.Lock()
p.bytesRateLimits = r
p.bytesRateLimitsMu.Unlock()
}
// topicOrBloomMatch matches against topic-interest if topic interest

View File

@ -34,15 +34,19 @@ type StatusOptions struct {
BloomFilter []byte `rlp:"key=1"`
LightNodeEnabled *bool `rlp:"key=2"`
ConfirmationsEnabled *bool `rlp:"key=3"`
RateLimits *common.RateLimits `rlp:"key=4"`
PacketRateLimits *common.RateLimits `rlp:"key=4"`
TopicInterest []common.TopicType `rlp:"key=5"`
BytesRateLimits *common.RateLimits `rlp:"key=6"`
}
func StatusOptionsFromHost(host common.WakuHost) StatusOptions {
opts := StatusOptions{}
rateLimits := host.RateLimits()
opts.RateLimits = &rateLimits
packetRateLimits := host.PacketRateLimits()
opts.PacketRateLimits = &packetRateLimits
bytesRateLimits := host.BytesRateLimits()
opts.BytesRateLimits = &bytesRateLimits
lightNode := host.LightClientMode()
opts.LightNodeEnabled = &lightNode
@ -114,8 +118,12 @@ func (o StatusOptions) WithDefaults() StatusOptions {
o.ConfirmationsEnabled = &confirmationsEnabled
}
if o.RateLimits == nil {
o.RateLimits = &common.RateLimits{}
if o.PacketRateLimits == nil {
o.PacketRateLimits = &common.RateLimits{}
}
if o.BytesRateLimits == nil {
o.BytesRateLimits = &common.RateLimits{}
}
if o.BloomFilter == nil {

View File

@ -20,12 +20,17 @@ func TestEncodeDecodeRLP(t *testing.T) {
BloomFilter: common.TopicType{0xaa, 0xbb, 0xcc, 0xdd}.ToBloom(),
LightNodeEnabled: &lightNodeEnabled,
ConfirmationsEnabled: &confirmationsEnabled,
RateLimits: &common.RateLimits{
PacketRateLimits: &common.RateLimits{
IPLimits: 10,
PeerIDLimits: 5,
TopicLimits: 1,
},
TopicInterest: []common.TopicType{{0x01}, {0x02}, {0x03}, {0x04}},
BytesRateLimits: &common.RateLimits{
IPLimits: 10,
PeerIDLimits: 5,
TopicLimits: 1,
},
}
data, err := rlp.EncodeToBytes(opts)
require.NoError(t, err)
@ -73,6 +78,7 @@ func TestInitRLPKeyFields(t *testing.T) {
3: 3,
4: 4,
5: 5,
6: 6,
}
kfi := map[statusOptionKey]int{
0: 0,
@ -81,6 +87,7 @@ func TestInitRLPKeyFields(t *testing.T) {
3: 3,
4: 4,
5: 5,
6: 6,
}
// Test that the kfi length matches the inited global keyFieldIdx length

View File

@ -394,16 +394,25 @@ func (w *Waku) LightClientModeConnectionRestricted() bool {
return w.settings.RestrictLightClientsConn
}
// RateLimiting returns RateLimits information.
func (w *Waku) RateLimits() common.RateLimits {
// PacketRateLimiting returns RateLimits information for packets
func (w *Waku) PacketRateLimits() common.RateLimits {
if w.rateLimiter == nil {
return common.RateLimits{}
}
return common.RateLimits{
PacketIPLimits: uint64(w.rateLimiter.PacketLimitPerSecIP),
PacketPeerIDLimits: uint64(w.rateLimiter.PacketLimitPerSecPeerID),
BytesIPLimits: uint64(w.rateLimiter.BytesLimitPerSecIP),
BytesPeerIDLimits: uint64(w.rateLimiter.BytesLimitPerSecPeerID),
IPLimits: uint64(w.rateLimiter.PacketLimitPerSecIP),
PeerIDLimits: uint64(w.rateLimiter.PacketLimitPerSecPeerID),
}
}
// BytesRateLimiting returns RateLimits information for bytes
func (w *Waku) BytesRateLimits() common.RateLimits {
if w.rateLimiter == nil {
return common.RateLimits{}
}
return common.RateLimits{
IPLimits: uint64(w.rateLimiter.BytesLimitPerSecIP),
PeerIDLimits: uint64(w.rateLimiter.BytesLimitPerSecPeerID),
}
}