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"
|
||||||
"github.com/status-im/status-go/protocol/anonmetrics"
|
"github.com/status-im/status-go/protocol/anonmetrics"
|
||||||
"github.com/status-im/status-go/protocol/common"
|
"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"
|
||||||
"github.com/status-im/status-go/protocol/communities/token"
|
"github.com/status-im/status-go/protocol/communities/token"
|
||||||
"github.com/status-im/status-go/protocol/protobuf"
|
"github.com/status-im/status-go/protocol/protobuf"
|
||||||
|
@ -550,17 +549,13 @@ func (s *Service) FillCollectibleMetadata(collectible *thirdparty.FullCollectibl
|
||||||
return fmt.Errorf("invalid communityID")
|
return fmt.Errorf("invalid communityID")
|
||||||
}
|
}
|
||||||
|
|
||||||
// FetchCommunityInfo should have been previously called once to ensure
|
community, err := s.messenger.FindCommunityInfoFromDB(communityID)
|
||||||
// that the latest version of the CommunityDescription is available in the DB
|
|
||||||
community, err := s.fetchCommunity(communityID, false)
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
if err == communities.ErrOrgNotFound {
|
||||||
}
|
|
||||||
|
|
||||||
if community == nil {
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
tokenMetadata, err := s.fetchCommunityCollectibleMetadata(community, id.ContractID)
|
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) {
|
func (s *Service) fetchCommunityFromStoreNodes(communityID string) (*thirdparty.CommunityInfo, error) {
|
||||||
community, err := s.fetchCommunity(communityID, true)
|
community, err := s.messenger.FetchCommunity(&protocol.FetchCommunityRequest{
|
||||||
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{
|
|
||||||
CommunityKey: communityID,
|
CommunityKey: communityID,
|
||||||
Shard: shard,
|
|
||||||
TryDatabase: false,
|
TryDatabase: false,
|
||||||
WaitForResponse: true,
|
WaitForResponse: true,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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)
|
community, err := s.messenger.FindCommunityInfoFromDB(communityID)
|
||||||
if err != nil {
|
if err != nil && err != communities.ErrOrgNotFound {
|
||||||
return nil, err
|
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) {
|
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 {
|
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 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).
|
// 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
|
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)
|
return cm.db.SetCommunityInfo(id, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cm *Manager) FetchCommunityInfo(communityID string) (*thirdparty.CommunityInfo, error) {
|
func (cm *Manager) fetchCommunityInfo(communityID string, fetcher func() (*thirdparty.CommunityInfo, error)) (*thirdparty.CommunityInfo, error) {
|
||||||
communityInfo, err := cm.communityInfoProvider.FetchCommunityInfo(communityID)
|
communityInfo, err := fetcher()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
dbErr := cm.setCommunityInfo(communityID, nil)
|
dbErr := cm.setCommunityInfo(communityID, nil)
|
||||||
if dbErr != nil {
|
if dbErr != nil {
|
||||||
|
@ -79,6 +79,18 @@ func (cm *Manager) FetchCommunityInfo(communityID string) (*thirdparty.Community
|
||||||
return communityInfo, err
|
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) {
|
func (cm *Manager) FetchCommunityMetadataAsync(communityID string) {
|
||||||
go func() {
|
go func() {
|
||||||
communityInfo, err := cm.FetchCommunityMetadata(communityID)
|
communityInfo, err := cm.FetchCommunityMetadata(communityID)
|
||||||
|
|
|
@ -14,4 +14,5 @@ type CommunityInfoProvider interface {
|
||||||
// Collectible-related methods
|
// Collectible-related methods
|
||||||
GetCommunityID(tokenURI string) string
|
GetCommunityID(tokenURI string) string
|
||||||
FillCollectibleMetadata(collectible *FullCollectibleData) error
|
FillCollectibleMetadata(collectible *FullCollectibleData) error
|
||||||
|
FetchCommunityInfoForCollectibles(communityID string, ids []CollectibleUniqueID) (*CommunityInfo, error)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue