fix: fetch community only when assets metadata is missing
fixes: status-im/status-desktop#14296
This commit is contained in:
parent
d3d155a5b2
commit
1ceb180e8a
|
@ -39,7 +39,6 @@ import (
|
|||
"github.com/status-im/status-go/protocol"
|
||||
"github.com/status-im/status-go/protocol/anonmetrics"
|
||||
"github.com/status-im/status-go/protocol/common"
|
||||
"github.com/status-im/status-go/protocol/common/shard"
|
||||
"github.com/status-im/status-go/protocol/communities"
|
||||
"github.com/status-im/status-go/protocol/communities/token"
|
||||
"github.com/status-im/status-go/protocol/protobuf"
|
||||
|
@ -550,17 +549,13 @@ func (s *Service) FillCollectibleMetadata(collectible *thirdparty.FullCollectibl
|
|||
return fmt.Errorf("invalid communityID")
|
||||
}
|
||||
|
||||
// FetchCommunityInfo should have been previously called once to ensure
|
||||
// that the latest version of the CommunityDescription is available in the DB
|
||||
community, err := s.fetchCommunity(communityID, false)
|
||||
|
||||
community, err := s.messenger.FindCommunityInfoFromDB(communityID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if community == nil {
|
||||
if err == communities.ErrOrgNotFound {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
tokenMetadata, err := s.fetchCommunityCollectibleMetadata(community, id.ContractID)
|
||||
|
||||
|
@ -637,48 +632,81 @@ func communityToInfo(community *communities.Community) *thirdparty.CommunityInfo
|
|||
}
|
||||
}
|
||||
|
||||
func (s *Service) FetchCommunityInfo(communityID string) (*thirdparty.CommunityInfo, error) {
|
||||
community, err := s.fetchCommunity(communityID, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return communityToInfo(community), nil
|
||||
}
|
||||
|
||||
func (s *Service) fetchCommunity(communityID string, fetchLatest bool) (*communities.Community, error) {
|
||||
if s.messenger == nil {
|
||||
return nil, fmt.Errorf("messenger not ready")
|
||||
}
|
||||
|
||||
// Try to fetch metadata from Messenger communities
|
||||
|
||||
// TODO: we need the shard information in the collectible to be able to retrieve info for
|
||||
// communities that have specific shards
|
||||
|
||||
if fetchLatest {
|
||||
// Try to fetch the latest version of the Community
|
||||
var shard *shard.Shard = nil // TODO: build this with info from token
|
||||
// NOTE: The community returned by this function will be nil if
|
||||
// the version we have in the DB is the latest available.
|
||||
_, err := s.messenger.FetchCommunity(&protocol.FetchCommunityRequest{
|
||||
func (s *Service) fetchCommunityFromStoreNodes(communityID string) (*thirdparty.CommunityInfo, error) {
|
||||
community, err := s.messenger.FetchCommunity(&protocol.FetchCommunityRequest{
|
||||
CommunityKey: communityID,
|
||||
Shard: shard,
|
||||
TryDatabase: false,
|
||||
WaitForResponse: true,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return communityToInfo(community), nil
|
||||
}
|
||||
|
||||
// Fetch latest community from store nodes.
|
||||
func (s *Service) FetchCommunityInfo(communityID string) (*thirdparty.CommunityInfo, error) {
|
||||
if s.messenger == nil {
|
||||
return nil, fmt.Errorf("messenger not ready")
|
||||
}
|
||||
|
||||
// Get the latest successfully fetched version of the Community
|
||||
community, err := s.messenger.FindCommunityInfoFromDB(communityID)
|
||||
if err != nil {
|
||||
if err != nil && err != communities.ErrOrgNotFound {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return community, nil
|
||||
// Fetch latest version from store nodes
|
||||
if community == nil || !community.IsControlNode() {
|
||||
return s.fetchCommunityFromStoreNodes(communityID)
|
||||
}
|
||||
|
||||
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")
|
||||
}
|
||||
|
||||
community, err := s.messenger.FindCommunityInfoFromDB(communityID)
|
||||
if err != nil && err != communities.ErrOrgNotFound {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if community == nil {
|
||||
return s.fetchCommunityFromStoreNodes(communityID)
|
||||
}
|
||||
|
||||
if community.IsControlNode() {
|
||||
return communityToInfo(community), nil
|
||||
}
|
||||
|
||||
contractIDs := func() map[string]thirdparty.ContractID {
|
||||
result := map[string]thirdparty.ContractID{}
|
||||
for _, id := range ids {
|
||||
result[id.HashKey()] = id.ContractID
|
||||
}
|
||||
return result
|
||||
}()
|
||||
|
||||
hasAllMetadata := true
|
||||
for _, contractID := range contractIDs {
|
||||
tokenMetadata, err := s.fetchCommunityCollectibleMetadata(community, contractID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if tokenMetadata == nil {
|
||||
hasAllMetadata = false
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !hasAllMetadata {
|
||||
return s.fetchCommunityFromStoreNodes(communityID)
|
||||
}
|
||||
|
||||
return communityToInfo(community), nil
|
||||
}
|
||||
|
||||
func (s *Service) fetchCommunityToken(communityID string, contractID thirdparty.ContractID) (*token.CommunityToken, error) {
|
||||
|
|
|
@ -728,7 +728,7 @@ func (o *Manager) fillCommunityID(asset *thirdparty.FullCollectibleData) error {
|
|||
}
|
||||
|
||||
func (o *Manager) fetchCommunityAssets(communityID string, communityAssets []*thirdparty.FullCollectibleData) error {
|
||||
communityInfo, err := o.communityManager.FetchCommunityInfo(communityID)
|
||||
communityInfo, err := o.communityManager.FetchCommunityInfoForCollectibles(communityID, idsFromAssets(communityAssets))
|
||||
|
||||
// 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).
|
||||
|
|
|
@ -204,3 +204,11 @@ func communityInfoToData(communityID string, community *thirdparty.CommunityInfo
|
|||
|
||||
return ret
|
||||
}
|
||||
|
||||
func idsFromAssets(assets []*thirdparty.FullCollectibleData) []thirdparty.CollectibleUniqueID {
|
||||
result := make([]thirdparty.CollectibleUniqueID, len(assets))
|
||||
for i, asset := range assets {
|
||||
result[i] = asset.CollectibleData.ID
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
|
|
@ -66,8 +66,8 @@ func (cm *Manager) setCommunityInfo(id string, c *thirdparty.CommunityInfo) (err
|
|||
return cm.db.SetCommunityInfo(id, c)
|
||||
}
|
||||
|
||||
func (cm *Manager) FetchCommunityInfo(communityID string) (*thirdparty.CommunityInfo, error) {
|
||||
communityInfo, err := cm.communityInfoProvider.FetchCommunityInfo(communityID)
|
||||
func (cm *Manager) fetchCommunityInfo(communityID string, fetcher func() (*thirdparty.CommunityInfo, error)) (*thirdparty.CommunityInfo, error) {
|
||||
communityInfo, err := fetcher()
|
||||
if err != nil {
|
||||
dbErr := cm.setCommunityInfo(communityID, nil)
|
||||
if dbErr != nil {
|
||||
|
@ -79,6 +79,18 @@ func (cm *Manager) FetchCommunityInfo(communityID string) (*thirdparty.Community
|
|||
return communityInfo, err
|
||||
}
|
||||
|
||||
func (cm *Manager) FetchCommunityInfo(communityID string) (*thirdparty.CommunityInfo, error) {
|
||||
return cm.fetchCommunityInfo(communityID, func() (*thirdparty.CommunityInfo, error) {
|
||||
return cm.communityInfoProvider.FetchCommunityInfo(communityID)
|
||||
})
|
||||
}
|
||||
|
||||
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)
|
||||
|
|
|
@ -14,4 +14,5 @@ type CommunityInfoProvider interface {
|
|||
// Collectible-related methods
|
||||
GetCommunityID(tokenURI string) string
|
||||
FillCollectibleMetadata(collectible *FullCollectibleData) error
|
||||
FetchCommunityInfoForCollectibles(communityID string, ids []CollectibleUniqueID) (*CommunityInfo, error)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue