From 475b7057412fc8f412f8b00c373beee5ee0d3ff6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=BDiga=20Kokelj?= Date: Tue, 6 Aug 2024 15:38:08 +0200 Subject: [PATCH] disable rate limiting on local testnet (#2005) --- testnet/launcher/docker.go | 1 + testnet/launcher/gateway/config.go | 21 +++++++---- testnet/launcher/gateway/docker.go | 1 + .../ratelimiter/rate_limiter.go | 36 +++++++++++++------ 4 files changed, 42 insertions(+), 17 deletions(-) diff --git a/testnet/launcher/docker.go b/testnet/launcher/docker.go index b92936caea..61c9d60603 100644 --- a/testnet/launcher/docker.go +++ b/testnet/launcher/docker.go @@ -191,6 +191,7 @@ func (t *Testnet) Start() error { gateway.WithTenNodeHTTPPort(13010), gateway.WithTenNodeWSPort(13011), gateway.WithTenNodeHost("validator-host"), + gateway.WithRateLimitUserComputeTime(0), // disable rate limiting for local network gateway.WithDockerImage("testnetobscuronet.azurecr.io/obscuronet/obscuro_gateway:latest"), ), ) diff --git a/testnet/launcher/gateway/config.go b/testnet/launcher/gateway/config.go index 507d5e6a19..bd72fc318b 100644 --- a/testnet/launcher/gateway/config.go +++ b/testnet/launcher/gateway/config.go @@ -1,16 +1,19 @@ package gateway +import "time" + // Option is a function that applies configs to a Config Object type Option = func(c *Config) // Config holds the properties that configure the package type Config struct { - tenNodeHost string - tenNodeHTTPPort int - tenNodeWSPort int - gatewayHTTPPort int - gatewayWSPort int - dockerImage string + tenNodeHost string + tenNodeHTTPPort int + tenNodeWSPort int + gatewayHTTPPort int + gatewayWSPort int + rateLimitUserComputeTime time.Duration + dockerImage string } func NewGatewayConfig(opts ...Option) *Config { @@ -58,3 +61,9 @@ func WithGatewayWSPort(i int) Option { c.gatewayWSPort = i } } + +func WithRateLimitUserComputeTime(d time.Duration) Option { + return func(c *Config) { + c.rateLimitUserComputeTime = d + } +} diff --git a/testnet/launcher/gateway/docker.go b/testnet/launcher/gateway/docker.go index cf11fbfeb6..b9dc38c397 100644 --- a/testnet/launcher/gateway/docker.go +++ b/testnet/launcher/gateway/docker.go @@ -33,6 +33,7 @@ func (n *DockerGateway) Start() error { "--nodeHost", n.cfg.tenNodeHost, "--dbType", "sqlite", "--logPath", "sys_out", + "--rateLimitUserComputeTime", fmt.Sprintf("%d", n.cfg.rateLimitUserComputeTime), } _, err := docker.StartNewContainer("gateway", n.cfg.dockerImage, cmds, []int{n.cfg.gatewayHTTPPort, n.cfg.gatewayWSPort}, nil, nil, nil, true) diff --git a/tools/walletextension/ratelimiter/rate_limiter.go b/tools/walletextension/ratelimiter/rate_limiter.go index f2be19ac41..05103b46f6 100644 --- a/tools/walletextension/ratelimiter/rate_limiter.go +++ b/tools/walletextension/ratelimiter/rate_limiter.go @@ -28,6 +28,10 @@ var zeroUUID uuid.UUID // AddRequest adds a new request interval to a user's current requests and returns the UUID. func (rl *RateLimiter) AddRequest(userID common.Address, interval RequestInterval) uuid.UUID { + // If the userComputeTime is 0, do nothing (rate limiting is disabled) + if rl.GetUserComputeTime() == 0 { + return zeroUUID + } rl.mu.Lock() defer rl.mu.Unlock() @@ -45,6 +49,11 @@ func (rl *RateLimiter) AddRequest(userID common.Address, interval RequestInterva // SetRequestEnd updates the end time of a request interval given its UUID. func (rl *RateLimiter) SetRequestEnd(userID common.Address, id uuid.UUID) { + // If the userComputeTime is 0, do nothing (rate limiting is disabled) + if rl.GetUserComputeTime() == 0 { + return + } + if user, userExists := rl.users[userID]; userExists { if request, requestExists := user.CurrentRequests[id]; requestExists { rl.mu.Lock() @@ -62,8 +71,8 @@ func (rl *RateLimiter) SetRequestEnd(userID common.Address, id uuid.UUID) { // CountOpenRequests counts the number of requests without an End time set. func (rl *RateLimiter) CountOpenRequests(userID common.Address) int { - rl.mu.Lock() - defer rl.mu.Unlock() + rl.mu.RLock() + defer rl.mu.RUnlock() var count int if user, exists := rl.users[userID]; exists { @@ -100,7 +109,7 @@ func (rl *RateLimiter) SumComputeTime(userID common.Address) time.Duration { } type RateLimiter struct { - mu sync.Mutex + mu sync.RWMutex users map[common.Address]*RateLimitUser userComputeTime time.Duration window time.Duration @@ -126,15 +135,15 @@ func (rl *RateLimiter) IncrementRateLimitedRequests() { // GetMaxConcurrentRequest returns the maximum number of concurrent requests allowed. func (rl *RateLimiter) GetMaxConcurrentRequest() uint32 { - rl.mu.Lock() - defer rl.mu.Unlock() + rl.mu.RLock() + defer rl.mu.RUnlock() return rl.maxConcurrentRequests } // GetUserComputeTime returns the user compute time func (rl *RateLimiter) GetUserComputeTime() time.Duration { - rl.mu.Lock() - defer rl.mu.Unlock() + rl.mu.RLock() + defer rl.mu.RUnlock() return rl.userComputeTime } @@ -146,8 +155,13 @@ func NewRateLimiter(rateLimitUserComputeTime time.Duration, rateLimitWindow time maxConcurrentRequests: concurrentRequestsLimit, logger: logger, } - go rl.logRateLimitedStats() - go rl.periodicPrune() + + // If the userComputeTime is 0 (rate limiting is disabled) we don't need to prune and log rate limited stats + if rl.GetUserComputeTime() != 0 { + go rl.logRateLimitedStats() + go rl.periodicPrune() + } + return rl } @@ -203,10 +217,10 @@ func (rl *RateLimiter) PruneRequests() { } } -// periodically prunes the requests that have ended before the rate limiter's window every 10 * window milliseconds +// periodically prunes the requests that have ended before the rate limiter's window milliseconds func (rl *RateLimiter) periodicPrune() { for { - time.Sleep(rl.window * 10) + time.Sleep(rl.window / 2) rl.PruneRequests() } }