From 759e5e5c7b7697168305eab6d69383a6914fd657 Mon Sep 17 00:00:00 2001 From: Patryk Osmaczko Date: Wed, 10 Apr 2024 11:21:41 +0200 Subject: [PATCH] fix_: improve `fetchCommunityAssets` performance fixes: #5038 --- services/ext/service.go | 53 ++++++++++++------- services/wallet/collectibles/manager.go | 23 +++----- services/wallet/collectibles/types.go | 2 +- services/wallet/community/manager.go | 10 +--- services/wallet/thirdparty/community_types.go | 3 +- 5 files changed, 45 insertions(+), 46 deletions(-) diff --git a/services/ext/service.go b/services/ext/service.go index a8a658128..6e8fb0b2e 100644 --- a/services/ext/service.go +++ b/services/ext/service.go @@ -52,6 +52,7 @@ import ( "github.com/status-im/status-go/services/ext/mailservers" mailserversDB "github.com/status-im/status-go/services/mailservers" "github.com/status-im/status-go/services/wallet" + "github.com/status-im/status-go/services/wallet/collectibles" w_common "github.com/status-im/status-go/services/wallet/common" "github.com/status-im/status-go/services/wallet/thirdparty" "github.com/status-im/status-go/wakuv2" @@ -533,7 +534,30 @@ func (s *Service) GetCommunityID(tokenURI string) string { return "" } -func (s *Service) FillCollectibleMetadata(collectible *thirdparty.FullCollectibleData) error { +func (s *Service) FillCollectiblesMetadata(communityID string, cs []*thirdparty.FullCollectibleData) (bool, error) { + if s.messenger == nil { + return false, fmt.Errorf("messenger not ready") + } + + community, err := s.fetchCommunityInfoForCollectibles(communityID, collectibles.IDsFromAssets(cs)) + if err != nil { + return false, err + } + if community == nil { + return false, nil + } + + for _, collectible := range cs { + err := s.FillCollectibleMetadata(community, collectible) + if err != nil { + return true, err + } + } + + return true, nil +} + +func (s *Service) FillCollectibleMetadata(community *communities.Community, collectible *thirdparty.FullCollectibleData) error { if s.messenger == nil { return fmt.Errorf("messenger not ready") } @@ -549,14 +573,6 @@ func (s *Service) FillCollectibleMetadata(collectible *thirdparty.FullCollectibl return fmt.Errorf("invalid communityID") } - community, err := s.messenger.FindCommunityInfoFromDB(communityID) - if err != nil { - if err == communities.ErrOrgNotFound { - return nil - } - return err - } - tokenMetadata, err := s.fetchCommunityCollectibleMetadata(community, id.ContractID) if err != nil { @@ -632,7 +648,7 @@ func communityToInfo(community *communities.Community) *thirdparty.CommunityInfo } } -func (s *Service) fetchCommunityFromStoreNodes(communityID string) (*thirdparty.CommunityInfo, error) { +func (s *Service) fetchCommunityFromStoreNodes(communityID string) (*communities.Community, error) { community, err := s.messenger.FetchCommunity(&protocol.FetchCommunityRequest{ CommunityKey: communityID, TryDatabase: false, @@ -641,7 +657,7 @@ func (s *Service) fetchCommunityFromStoreNodes(communityID string) (*thirdparty. if err != nil { return nil, err } - return communityToInfo(community), nil + return community, nil } // Fetch latest community from store nodes. @@ -657,18 +673,17 @@ func (s *Service) FetchCommunityInfo(communityID string) (*thirdparty.CommunityI // Fetch latest version from store nodes if community == nil || !community.IsControlNode() { - return s.fetchCommunityFromStoreNodes(communityID) + community, err = s.fetchCommunityFromStoreNodes(communityID) + if err != nil { + return nil, err + } } return communityToInfo(community), nil } // Fetch latest community from store nodes only if any collectibles data is missing. -func (s *Service) FetchCommunityInfoForCollectibles(communityID string, ids []thirdparty.CollectibleUniqueID) (*thirdparty.CommunityInfo, error) { - if s.messenger == nil { - return nil, fmt.Errorf("messenger not ready") - } - +func (s *Service) fetchCommunityInfoForCollectibles(communityID string, ids []thirdparty.CollectibleUniqueID) (*communities.Community, error) { community, err := s.messenger.FindCommunityInfoFromDB(communityID) if err != nil && err != communities.ErrOrgNotFound { return nil, err @@ -679,7 +694,7 @@ func (s *Service) FetchCommunityInfoForCollectibles(communityID string, ids []th } if community.IsControlNode() { - return communityToInfo(community), nil + return community, nil } contractIDs := func() map[string]thirdparty.ContractID { @@ -706,7 +721,7 @@ func (s *Service) FetchCommunityInfoForCollectibles(communityID string, ids []th return s.fetchCommunityFromStoreNodes(communityID) } - return communityToInfo(community), nil + return community, nil } func (s *Service) fetchCommunityToken(communityID string, contractID thirdparty.ContractID) (*token.CommunityToken, error) { diff --git a/services/wallet/collectibles/manager.go b/services/wallet/collectibles/manager.go index 5f5817284..f3d448f6f 100644 --- a/services/wallet/collectibles/manager.go +++ b/services/wallet/collectibles/manager.go @@ -728,25 +728,16 @@ func (o *Manager) fillCommunityID(asset *thirdparty.FullCollectibleData) error { } func (o *Manager) fetchCommunityAssets(communityID string, communityAssets []*thirdparty.FullCollectibleData) error { - communityInfo, err := o.communityManager.FetchCommunityInfoForCollectibles(communityID, idsFromAssets(communityAssets)) + communityFound, err := o.communityManager.FillCollectiblesMetadata(communityID, communityAssets) + if err != nil { + log.Error("FillCollectiblesMetadata failed", "communityID", communityID, "err", err) + } else if !communityFound { + log.Warn("fetchCommunityAssets community not found", "communityID", communityID) + } // If the community is found, we update the DB. // If the community is not found, we only insert new entries to the DB (don't replace what is already there). - allowUpdate := false - if err != nil { - log.Error("fetchCommunityInfo failed", "communityID", communityID, "err", err) - } else if communityInfo == nil { - log.Warn("fetchCommunityAssets community not found", "communityID", communityID) - } else { - for _, communityAsset := range communityAssets { - err := o.communityManager.FillCollectibleMetadata(communityAsset) - if err != nil { - log.Error("FillCollectibleMetadata failed", "communityID", communityID, "err", err) - return err - } - } - allowUpdate = true - } + allowUpdate := communityFound collectiblesData := make([]thirdparty.CollectibleData, 0, len(communityAssets)) collectionsData := make([]thirdparty.CollectionData, 0, len(communityAssets)) diff --git a/services/wallet/collectibles/types.go b/services/wallet/collectibles/types.go index 583c8e751..0c4588b3a 100644 --- a/services/wallet/collectibles/types.go +++ b/services/wallet/collectibles/types.go @@ -205,7 +205,7 @@ func communityInfoToData(communityID string, community *thirdparty.CommunityInfo return ret } -func idsFromAssets(assets []*thirdparty.FullCollectibleData) []thirdparty.CollectibleUniqueID { +func IDsFromAssets(assets []*thirdparty.FullCollectibleData) []thirdparty.CollectibleUniqueID { result := make([]thirdparty.CollectibleUniqueID, len(assets)) for i, asset := range assets { result[i] = asset.CollectibleData.ID diff --git a/services/wallet/community/manager.go b/services/wallet/community/manager.go index f5e5ea9c8..a586cedde 100644 --- a/services/wallet/community/manager.go +++ b/services/wallet/community/manager.go @@ -58,8 +58,8 @@ func (cm *Manager) GetCommunityID(tokenURI string) string { return cm.communityInfoProvider.GetCommunityID(tokenURI) } -func (cm *Manager) FillCollectibleMetadata(c *thirdparty.FullCollectibleData) error { - return cm.communityInfoProvider.FillCollectibleMetadata(c) +func (cm *Manager) FillCollectiblesMetadata(communityID string, cs []*thirdparty.FullCollectibleData) (bool, error) { + return cm.communityInfoProvider.FillCollectiblesMetadata(communityID, cs) } func (cm *Manager) setCommunityInfo(id string, c *thirdparty.CommunityInfo) (err error) { @@ -85,12 +85,6 @@ func (cm *Manager) FetchCommunityInfo(communityID string) (*thirdparty.Community }) } -func (cm *Manager) FetchCommunityInfoForCollectibles(communityID string, ids []thirdparty.CollectibleUniqueID) (*thirdparty.CommunityInfo, error) { - return cm.fetchCommunityInfo(communityID, func() (*thirdparty.CommunityInfo, error) { - return cm.communityInfoProvider.FetchCommunityInfoForCollectibles(communityID, ids) - }) -} - func (cm *Manager) FetchCommunityMetadataAsync(communityID string) { go func() { communityInfo, err := cm.FetchCommunityMetadata(communityID) diff --git a/services/wallet/thirdparty/community_types.go b/services/wallet/thirdparty/community_types.go index c97ef276f..216f22ee9 100644 --- a/services/wallet/thirdparty/community_types.go +++ b/services/wallet/thirdparty/community_types.go @@ -13,6 +13,5 @@ type CommunityInfoProvider interface { // Collectible-related methods GetCommunityID(tokenURI string) string - FillCollectibleMetadata(collectible *FullCollectibleData) error - FetchCommunityInfoForCollectibles(communityID string, ids []CollectibleUniqueID) (*CommunityInfo, error) + FillCollectiblesMetadata(communityID string, cs []*FullCollectibleData) (bool, error) }