From 50c65411c8b554234c8411f3d33a328c826abb40 Mon Sep 17 00:00:00 2001 From: Dario Gabriel Lipicar Date: Thu, 20 Feb 2025 13:30:55 -0300 Subject: [PATCH] chore_: added small util to analyze token stores --- Makefile | 2 + services/wallet/token/analyzer/main.go | 73 +++++++++++++++++++++ services/wallet/token/token.go | 6 +- services/wallet/token/tokenstore.go | 4 +- services/wallet/token/uniswap_tokenstore.go | 2 +- 5 files changed, 81 insertions(+), 6 deletions(-) create mode 100644 services/wallet/token/analyzer/main.go diff --git a/Makefile b/Makefile index d4be1f241..ec3382f0e 100644 --- a/Makefile +++ b/Makefile @@ -264,6 +264,8 @@ generate-contracts: go generate ./contracts download-uniswap-tokens: go run ./services/wallet/token/downloader/main.go +analyze-token-stores: + go run ./services/wallet/token/analyzer/main.go prepare-release: clean-release mkdir -p $(RELEASE_DIR) diff --git a/services/wallet/token/analyzer/main.go b/services/wallet/token/analyzer/main.go new file mode 100644 index 000000000..c8f08e68f --- /dev/null +++ b/services/wallet/token/analyzer/main.go @@ -0,0 +1,73 @@ +package main + +import ( + "fmt" + + token "github.com/status-im/status-go/services/wallet/token" +) + +func main() { + statusStore := token.NewDefaultStore() + otherStores := []token.Store{token.NewUniswapStore()} + allStores := append([]token.Store{statusStore}, otherStores...) + + storePerName := map[string]token.Store{} + for _, store := range allStores { + if _, ok := storePerName[store.GetName()]; !ok { + storePerName[store.GetName()] = store + } else { + fmt.Printf("Duplicate store names: %s\n", store.GetName()) + } + } + + fmt.Println("") + tokensPerStore := make(map[string]map[string]*token.Token) // map[store][tokenID]*token.Token + for storeName, store := range storePerName { + fmt.Printf("Analizying store: %s\n", storeName) + tokens := store.GetTokens() + fmt.Printf("Total number of tokens: %d\n", len(tokens)) + + tokensPerStore[storeName] = make(map[string]*token.Token) + tokensPerChainID := make(map[uint64][]*token.Token) // map[chainID]*token.Token + for _, chainToken := range tokens { + if _, ok := tokensPerChainID[chainToken.ChainID]; !ok { + tokensPerChainID[chainToken.ChainID] = make([]*token.Token, 0, len(tokens)) + } + tokensPerChainID[chainToken.ChainID] = append(tokensPerChainID[chainToken.ChainID], chainToken) + + id := getTokenID(chainToken) + if _, ok := tokensPerStore[storeName][id]; !ok { + tokensPerStore[storeName][id] = chainToken + } else { + fmt.Printf("Duplicate token for id: %s\n", id) + } + } + + for chainID, chainTokens := range tokensPerChainID { + fmt.Printf("Total number of tokens for chain %d: %d\n", chainID, len(chainTokens)) + } + fmt.Println("") + } + + fmt.Println("Cross-analyzing stores") + statusStoreName := statusStore.GetName() + dupesFound := false + for tokenID, token := range tokensPerStore[statusStore.GetName()] { + for otherStoreName, otherTokensPerChain := range tokensPerStore { + if otherStoreName == statusStoreName { + continue + } + if _, ok := otherTokensPerChain[tokenID]; ok { + dupesFound = true + fmt.Printf("Token with id '%s' and symbol '%s' found in stores %s and %s\n", tokenID, token.Symbol, statusStoreName, otherStoreName) + } + } + } + if !dupesFound { + fmt.Println("No duplicates found") + } +} + +func getTokenID(token *token.Token) string { + return fmt.Sprintf("%d - %s", token.ChainID, token.Address.Hex()) +} diff --git a/services/wallet/token/token.go b/services/wallet/token/token.go index 9b7c21a3f..efea7bb9a 100644 --- a/services/wallet/token/token.go +++ b/services/wallet/token/token.go @@ -106,7 +106,7 @@ type Manager struct { RPCClient rpc.ClientInterface ContractMaker *contracts.ContractMaker networkManager network.ManagerInterface - stores []store // Set on init, not changed afterwards + stores []Store // Set on init, not changed afterwards communityTokensDB *communitytokensdatabase.Database communityManager *community.Manager mediaServer *server.MediaServer @@ -136,7 +136,7 @@ func mergeTokens(sliceLists [][]*Token) []*Token { return res } -func prepareTokens(networkManager network.ManagerInterface, stores []store) []*Token { +func prepareTokens(networkManager network.ManagerInterface, stores []Store) []*Token { tokens := make([]*Token, 0) networks, err := networkManager.GetAll() @@ -175,7 +175,7 @@ func NewTokenManager( tokenBalancesStorage TokenBalancesStorage, ) *Manager { maker, _ := contracts.NewContractMaker(RPCClient) - stores := []store{newUniswapStore(), newDefaultStore()} + stores := []Store{NewUniswapStore(), NewDefaultStore()} tokens := prepareTokens(networkManager, stores) return &Manager{ diff --git a/services/wallet/token/tokenstore.go b/services/wallet/token/tokenstore.go index 73183cf57..882e65e7a 100644 --- a/services/wallet/token/tokenstore.go +++ b/services/wallet/token/tokenstore.go @@ -4,7 +4,7 @@ import ( "github.com/ethereum/go-ethereum/common" ) -type store interface { +type Store interface { GetTokens() []*Token GetVersion() string GetSource() string @@ -55,7 +55,7 @@ func (s *DefaultStore) GetSource() string { return "https://github.com/status-im/status-go/blob/develop/services/wallet/token/tokenstore.go" } -func newDefaultStore() *DefaultStore { +func NewDefaultStore() *DefaultStore { return &DefaultStore{ TokenListID: []*Token{ &Token{ diff --git a/services/wallet/token/uniswap_tokenstore.go b/services/wallet/token/uniswap_tokenstore.go index b717d47cd..276d93070 100644 --- a/services/wallet/token/uniswap_tokenstore.go +++ b/services/wallet/token/uniswap_tokenstore.go @@ -3,7 +3,7 @@ package token type uniswapStore struct { } -func newUniswapStore() *uniswapStore { +func NewUniswapStore() *uniswapStore { return &uniswapStore{} }