diff --git a/rpc/chain/client.go b/rpc/chain/client.go index c0d695057..fa807bc7a 100644 --- a/rpc/chain/client.go +++ b/rpc/chain/client.go @@ -237,7 +237,7 @@ func (c *ClientWithFallback) IsConnected() bool { func (c *ClientWithFallback) makeCall(ctx context.Context, main func() ([]any, error), fallback func() ([]any, error)) ([]any, error) { if c.commonLimiter != nil { - if limited, err := c.commonLimiter.IsLimitReached(c.tag); limited { + if allow, err := c.commonLimiter.Allow(c.tag); !allow { return nil, fmt.Errorf("tag=%s, %w", c.tag, err) } } diff --git a/rpc/chain/rpc_limiter.go b/rpc/chain/rpc_limiter.go index b8aee8c1a..1c5cabeae 100644 --- a/rpc/chain/rpc_limiter.go +++ b/rpc/chain/rpc_limiter.go @@ -63,9 +63,9 @@ type RequestData struct { } type RequestLimiter interface { - SetMaxRequests(tag string, maxRequests int, interval time.Duration) error - GetMaxRequests(tag string) (*RequestData, error) - IsLimitReached(tag string) (bool, error) + SetLimit(tag string, maxRequests int, interval time.Duration) error + GetLimit(tag string) (*RequestData, error) + Allow(tag string) (bool, error) } type RPCRequestLimiter struct { @@ -78,7 +78,7 @@ func NewRequestLimiter(storage RequestsStorage) *RPCRequestLimiter { } } -func (rl *RPCRequestLimiter) SetMaxRequests(tag string, maxRequests int, interval time.Duration) error { +func (rl *RPCRequestLimiter) SetLimit(tag string, maxRequests int, interval time.Duration) error { err := rl.saveToStorage(tag, maxRequests, interval, 0, time.Now()) if err != nil { log.Error("Failed to save request data to storage", "error", err) @@ -88,7 +88,7 @@ func (rl *RPCRequestLimiter) SetMaxRequests(tag string, maxRequests int, interva return nil } -func (rl *RPCRequestLimiter) GetMaxRequests(tag string) (*RequestData, error) { +func (rl *RPCRequestLimiter) GetLimit(tag string) (*RequestData, error) { data, err := rl.storage.Get(tag) if err != nil { return nil, err @@ -115,37 +115,38 @@ func (rl *RPCRequestLimiter) saveToStorage(tag string, maxRequests int, interval return nil } -func (rl *RPCRequestLimiter) IsLimitReached(tag string) (bool, error) { +func (rl *RPCRequestLimiter) Allow(tag string) (bool, error) { data, err := rl.storage.Get(tag) + log.Info("Allow", "data", data) if err != nil { - return false, err + return true, err } if data == nil { - return false, nil + return true, nil } // Check if a number of requests is over the limit within the interval if time.Since(data.CreatedAt) < data.Period { if data.NumReqs >= data.MaxReqs { - return true, nil + return false, nil } err := rl.saveToStorage(tag, data.MaxReqs, data.Period, data.NumReqs+1, data.CreatedAt) if err != nil { - return false, err + return true, err } - return false, nil + return true, nil } // Reset the number of requests if the interval has passed err = rl.saveToStorage(tag, data.MaxReqs, data.Period, 0, time.Now()) if err != nil { - return false, err + return true, err // still allow if failed to save } - return false, nil + return true, nil } type RPCRpsLimiter struct { diff --git a/rpc/chain/rpc_limiter_test.go b/rpc/chain/rpc_limiter_test.go index e922f6ca9..f6c53b1e3 100644 --- a/rpc/chain/rpc_limiter_test.go +++ b/rpc/chain/rpc_limiter_test.go @@ -13,7 +13,7 @@ func setupTest() (*InMemRequestsMapStorage, RequestLimiter) { return storage, rl } -func TestSetMaxRequests(t *testing.T) { +func TestSetLimit(t *testing.T) { storage, rl := setupTest() // Define test inputs @@ -21,8 +21,8 @@ func TestSetMaxRequests(t *testing.T) { maxRequests := 10 interval := time.Second - // Call the SetMaxRequests method - err := rl.SetMaxRequests(tag, maxRequests, interval) + // Call the SetLimit method + err := rl.SetLimit(tag, maxRequests, interval) require.NoError(t, err) // Verify that the data was saved to storage correctly @@ -34,27 +34,27 @@ func TestSetMaxRequests(t *testing.T) { require.Equal(t, 0, data.NumReqs) } -func TestGetMaxRequests(t *testing.T) { +func TestGetLimit(t *testing.T) { storage, rl := setupTest() + // Define test inputs data := &RequestData{ Tag: "testTag", Period: time.Second, MaxReqs: 10, NumReqs: 1, } - // Define test inputs storage.Set(data) - // Call the GetMaxRequests method - ret, err := rl.GetMaxRequests(data.Tag) + // Call the GetLimit method + ret, err := rl.GetLimit(data.Tag) require.NoError(t, err) // Verify the returned data require.Equal(t, data, ret) } -func TestIsLimitReachedWithinPeriod(t *testing.T) { +func TestAllowWithinPeriod(t *testing.T) { storage, rl := setupTest() // Define test inputs @@ -71,22 +71,22 @@ func TestIsLimitReachedWithinPeriod(t *testing.T) { } storage.Set(data) - // Call the IsLimitReached method + // Call the Allow method for i := 0; i < maxRequests; i++ { - limitReached, err := rl.IsLimitReached(tag) + allow, err := rl.Allow(tag) require.NoError(t, err) // Verify the result - require.False(t, limitReached) + require.True(t, allow) } - // Call the IsLimitReached method again - limitReached, err := rl.IsLimitReached(tag) + // Call the Allow method again + allow, err := rl.Allow(tag) require.NoError(t, err) - require.True(t, limitReached) + require.False(t, allow) } -func TestIsLimitReachedWhenPeriodPassed(t *testing.T) { +func TestAllowWhenPeriodPassed(t *testing.T) { storage, rl := setupTest() // Define test inputs @@ -104,10 +104,10 @@ func TestIsLimitReachedWhenPeriodPassed(t *testing.T) { } storage.Set(data) - // Call the IsLimitReached method - limitReached, err := rl.IsLimitReached(tag) + // Call the Allow method + allow, err := rl.Allow(tag) require.NoError(t, err) // Verify the result - require.False(t, limitReached) + require.True(t, allow) } diff --git a/services/wallet/transfer/commands_sequential.go b/services/wallet/transfer/commands_sequential.go index 583c9adde..70842339b 100644 --- a/services/wallet/transfer/commands_sequential.go +++ b/services/wallet/transfer/commands_sequential.go @@ -29,8 +29,8 @@ const ( transferHistoryTag = "transfer_history" newTransferHistoryTag = "new_transfer_history" - transferHistoryMaxRequests = 10000 - transferHistoryMaxRequestsPeriod = 24 * time.Hour + transferHistoryLimit = 10000 + transferHistoryLimitPeriod = 24 * time.Hour ) type nonceInfo struct { @@ -1123,7 +1123,7 @@ func (c *loadBlocksAndTransfersCommand) fetchHistoryBlocksForAccount(group *asyn chainClient := chain.ClientWithTag(c.chainClient, transferHistoryTag) limiter := chain.NewRequestLimiter(chain.NewInMemRequestsMapStorage()) - limiter.SetMaxRequests(transferHistoryTag, transferHistoryMaxRequests, transferHistoryMaxRequestsPeriod) + limiter.SetLimit(transferHistoryTag, transferHistoryLimit, transferHistoryLimitPeriod) chainClient.SetLimiter(limiter) fbc := &findBlocksCommand{ diff --git a/services/wallet/transfer/commands_sequential_test.go b/services/wallet/transfer/commands_sequential_test.go index 7f93360d7..7b1e47893 100644 --- a/services/wallet/transfer/commands_sequential_test.go +++ b/services/wallet/transfer/commands_sequential_test.go @@ -1047,7 +1047,7 @@ func setupFindBlocksCommand(t *testing.T, accountAddress common.Address, fromBlo // Reimplement the common function that is called from every method to check for the limit countAndlog = func(tc *TestClient, method string, params ...interface{}) error { if tc.GetLimiter() != nil { - if limited, _ := tc.GetLimiter().IsLimitReached(transferHistoryTag); limited { + if allow, _ := tc.GetLimiter().Allow(transferHistoryTag); !allow { t.Log("ERROR: requests over limit") return chain.ErrRequestsOverLimit } @@ -1180,7 +1180,7 @@ func TestFindBlocksCommandWithLimiter(t *testing.T) { fbc, tc, blockChannel, _ := setupFindBlocksCommand(t, accountAddress, big.NewInt(0), big.NewInt(20), rangeSize, balances, nil, nil, nil, nil) limiter := chain.NewRequestLimiter(chain.NewInMemRequestsMapStorage()) - limiter.SetMaxRequests(transferHistoryTag, maxRequests, time.Hour) + limiter.SetLimit(transferHistoryTag, maxRequests, time.Hour) tc.SetLimiter(limiter) ctx := context.Background() @@ -1207,7 +1207,7 @@ func TestFindBlocksCommandWithLimiterTagDifferentThanTransfers(t *testing.T) { fbc, tc, blockChannel, _ := setupFindBlocksCommand(t, accountAddress, big.NewInt(0), big.NewInt(20), rangeSize, balances, outgoingERC20Transfers, incomingERC20Transfers, nil, nil) limiter := chain.NewRequestLimiter(chain.NewInMemRequestsMapStorage()) - limiter.SetMaxRequests("some-other-tag-than-transfer-history", maxRequests, time.Hour) + limiter.SetLimit("some-other-tag-than-transfer-history", maxRequests, time.Hour) tc.SetLimiter(limiter) ctx := context.Background()