diff --git a/rpc/chain/client.go b/rpc/chain/client.go index 29ebf8f0b..3250a4e99 100644 --- a/rpc/chain/client.go +++ b/rpc/chain/client.go @@ -2,6 +2,7 @@ package chain import ( "context" + "errors" "fmt" "math/big" "strings" @@ -1005,7 +1006,7 @@ func (c *ClientWithFallback) SetWalletNotifier(notifier func(chainId uint64, mes func (c *ClientWithFallback) toggleConnectionState(err error) { connected := true if err != nil { - if !isVMError(err) && err != ErrRequestsOverLimit { + if !isVMError(err) && !errors.Is(ErrRequestsOverLimit, err) { connected = false } } diff --git a/rpc/chain/rpc_limiter_test.go b/rpc/chain/rpc_limiter_test.go index 202ac4ddc..675a0a01b 100644 --- a/rpc/chain/rpc_limiter_test.go +++ b/rpc/chain/rpc_limiter_test.go @@ -44,7 +44,8 @@ func TestGetLimit(t *testing.T) { MaxReqs: 10, NumReqs: 1, } - storage.Set(data) + err := storage.Set(data) + require.NoError(t, err) // Call the GetLimit method ret, err := rl.GetLimit(data.Tag) @@ -69,7 +70,8 @@ func TestAllowWithinPeriod(t *testing.T) { CreatedAt: time.Now(), MaxReqs: maxRequests, } - storage.Set(data) + err := storage.Set(data) + require.NoError(t, err) // Call the Allow method for i := 0; i < maxRequests; i++ { @@ -102,7 +104,8 @@ func TestAllowWhenPeriodPassed(t *testing.T) { MaxReqs: maxRequests, NumReqs: maxRequests, } - storage.Set(data) + err := storage.Set(data) + require.NoError(t, err) // Call the Allow method allow, err := rl.Allow(tag) diff --git a/services/rpcstats/api.go b/services/rpcstats/api.go index 896a9b5e3..12e7ad708 100644 --- a/services/rpcstats/api.go +++ b/services/rpcstats/api.go @@ -2,6 +2,7 @@ package rpcstats import ( "context" + "sync" ) // PublicAPI represents a set of APIs from the namespace. @@ -26,13 +27,24 @@ type RPCStats struct { // GetStats returns RPC usage stats func (api *PublicAPI) GetStats(context context.Context) (RPCStats, error) { - total, perMethod := getStats() + total, perMethod, perMethodPerTag := getStats() counterPerMethod := make(map[string]uint) perMethod.Range(func(key, value interface{}) bool { counterPerMethod[key.(string)] = value.(uint) return true }) + perMethodPerTag.Range(func(key, value interface{}) bool { + tag := key.(string) + methods := value.(*sync.Map) + methods.Range(func(key, value interface{}) bool { + method := key.(string) + count := value.(uint) + counterPerMethod[method+"_"+tag] = count + return true + }) + return true + }) return RPCStats{ Total: total, diff --git a/services/rpcstats/stats.go b/services/rpcstats/stats.go index 27a5484da..2496c1738 100644 --- a/services/rpcstats/stats.go +++ b/services/rpcstats/stats.go @@ -2,14 +2,12 @@ package rpcstats import ( "sync" - - "github.com/ethereum/go-ethereum/log" ) type RPCUsageStats struct { total uint - counterPerMethod sync.Map - counterPerMethodPerTag sync.Map + counterPerMethod *sync.Map + counterPerMethodPerTag *sync.Map } var stats *RPCUsageStats @@ -17,36 +15,25 @@ var stats *RPCUsageStats func getInstance() *RPCUsageStats { if stats == nil { stats = &RPCUsageStats{} + stats.counterPerMethod = &sync.Map{} + stats.counterPerMethodPerTag = &sync.Map{} } return stats } -func getStats() (uint, sync.Map) { +func getStats() (uint, *sync.Map, *sync.Map) { stats := getInstance() - return stats.total, stats.counterPerMethod + return stats.total, stats.counterPerMethod, stats.counterPerMethodPerTag } -// func getStatsWithTag(tag string) (sync.Map, bool) { -// stats := getInstance() -// value, ok := stats.counterPerMethodPerTag.Load(tag) -// return value.(sync.Map), ok -// } - func resetStats() { stats := getInstance() stats.total = 0 - stats.counterPerMethod = sync.Map{} - stats.counterPerMethodPerTag = sync.Map{} + stats.counterPerMethod = &sync.Map{} + stats.counterPerMethodPerTag = &sync.Map{} } -// func resetStatsWithTag(tag string) { -// stats := getInstance() -// stats.counterPerMethodPerTag.Delete(tag) -// } - func CountCall(method string) { - log.Info("CountCall", "method", method) - stats := getInstance() stats.total++ value, _ := stats.counterPerMethod.LoadOrStore(method, uint(0)) @@ -60,12 +47,10 @@ func CountCallWithTag(method string, tag string) { } stats := getInstance() - value, _ := stats.counterPerMethodPerTag.LoadOrStore(tag, sync.Map{}) - methodMap := value.(sync.Map) + value, _ := stats.counterPerMethodPerTag.LoadOrStore(tag, &sync.Map{}) + methodMap := value.(*sync.Map) value, _ = methodMap.LoadOrStore(method, uint(0)) methodMap.Store(method, value.(uint)+1) - log.Info("CountCallWithTag", "method", method, "tag", tag, "count", value.(uint)+1) - CountCall(method) } diff --git a/services/wallet/transfer/commands_sequential.go b/services/wallet/transfer/commands_sequential.go index ee243f43a..2eb20fb59 100644 --- a/services/wallet/transfer/commands_sequential.go +++ b/services/wallet/transfer/commands_sequential.go @@ -1127,8 +1127,14 @@ func (c *loadBlocksAndTransfersCommand) fetchHistoryBlocksForAccount(group *asyn chainClient := chain.ClientWithTag(c.chainClient, accountTag, transferHistoryTag) storage := chain.NewLimitsDBStorage(c.db.client) limiter := chain.NewRequestLimiter(storage) - limiter.SetLimit(accountTag, transferHistoryLimitPerAccount, transferHistoryLimitPeriod) - limiter.SetLimit(transferHistoryTag, transferHistoryLimit, transferHistoryLimitPeriod) + err := limiter.SetLimit(accountTag, transferHistoryLimitPerAccount, transferHistoryLimitPeriod) + if err != nil { + log.Error("fetchHistoryBlocksForAccount SetLimit", "error", err, "accountTag", accountTag) + } + err = limiter.SetLimit(transferHistoryTag, transferHistoryLimit, transferHistoryLimitPeriod) + if err != nil { + log.Error("fetchHistoryBlocksForAccount SetLimit", "error", err, "groupTag", transferHistoryTag) + } chainClient.SetLimiter(limiter) fbc := &findBlocksCommand{ diff --git a/services/wallet/transfer/commands_sequential_test.go b/services/wallet/transfer/commands_sequential_test.go index 69c26daff..de4485ae0 100644 --- a/services/wallet/transfer/commands_sequential_test.go +++ b/services/wallet/transfer/commands_sequential_test.go @@ -332,7 +332,10 @@ var ethscanAddress = common.HexToAddress("0x000000000000000000000000000000000077 var balanceCheckAddress = common.HexToAddress("0x0000000000000000000000000000000010777333") func (tc *TestClient) CodeAt(ctx context.Context, contract common.Address, blockNumber *big.Int) ([]byte, error) { - tc.countAndlog("CodeAt", fmt.Sprintf("contract: %s, blockNumber: %d", contract, blockNumber)) + err := tc.countAndlog("CodeAt", fmt.Sprintf("contract: %s, blockNumber: %d", contract, blockNumber)) + if err != nil { + return nil, err + } if ethscanAddress == contract || balanceCheckAddress == contract { return []byte{1}, nil @@ -1182,7 +1185,8 @@ 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.SetLimit(transferHistoryTag, maxRequests, time.Hour) + err := limiter.SetLimit(transferHistoryTag, maxRequests, time.Hour) + require.NoError(t, err) tc.SetLimiter(limiter) tc.tag = transferHistoryTag @@ -1210,7 +1214,8 @@ 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.SetLimit("some-other-tag-than-transfer-history", maxRequests, time.Hour) + err := limiter.SetLimit("some-other-tag-than-transfer-history", maxRequests, time.Hour) + require.NoError(t, err) tc.SetLimiter(limiter) ctx := context.Background() @@ -1247,8 +1252,10 @@ func TestFindBlocksCommandWithLimiterForMultipleAccountsSameGroup(t *testing.T) tc.groupTag = transferHistoryTag limiter1 := chain.NewRequestLimiter(storage) - limiter1.SetLimit(transferHistoryTag, maxRequestsTotal, time.Hour) - limiter1.SetLimit(transferHistoryTag+account1.String(), limit1, time.Hour) + err := limiter1.SetLimit(transferHistoryTag, maxRequestsTotal, time.Hour) + require.NoError(t, err) + err = limiter1.SetLimit(transferHistoryTag+account1.String(), limit1, time.Hour) + require.NoError(t, err) tc.SetLimiter(limiter1) // Set up the second account @@ -1256,8 +1263,10 @@ func TestFindBlocksCommandWithLimiterForMultipleAccountsSameGroup(t *testing.T) tc2.tag = transferHistoryTag + account2.String() tc2.groupTag = transferHistoryTag limiter2 := chain.NewRequestLimiter(storage) - limiter2.SetLimit(transferHistoryTag, maxRequestsTotal, time.Hour) - limiter2.SetLimit(transferHistoryTag+account2.String(), limit2, time.Hour) + err = limiter2.SetLimit(transferHistoryTag, maxRequestsTotal, time.Hour) + require.NoError(t, err) + err = limiter2.SetLimit(transferHistoryTag+account2.String(), limit2, time.Hour) + require.NoError(t, err) tc2.SetLimiter(limiter2) fbc2.blocksLoadedCh = blockChannel