From d197857034109f71c3ab529177ce5289839e3763 Mon Sep 17 00:00:00 2001 From: Jonathan Rainville Date: Tue, 26 Nov 2024 14:15:27 -0500 Subject: [PATCH] refactor(server_media)_: pass a func to get the images instead of using the cache The community cache that the image server was using was not intended to be used for that. It can be invalidated at any moment. Also, it did not contain changes made by admins (admin events). Using this new approach, we pass functions from the community manager to the media server so that it can have access to the correct community description. --- protocol/communities/manager.go | 17 ++++++++++++++ server/handlers.go | 36 +++++------------------------- server/server_media.go | 38 +++++++++++++++++++++++++++----- server/server_media_interface.go | 4 ++++ 4 files changed, 59 insertions(+), 36 deletions(-) diff --git a/protocol/communities/manager.go b/protocol/communities/manager.go index be5a5b659..c58e51eff 100644 --- a/protocol/communities/manager.go +++ b/protocol/communities/manager.go @@ -477,6 +477,23 @@ func NewManager( manager.forceMembersReevaluation = make(map[string]chan struct{}, 10) } + if mediaServer != nil { + mediaServer.SetCommunityImageReader(func(communityID string) (map[string]*protobuf.IdentityImage, error) { + community, err := manager.GetByIDString(communityID) + if err != nil { + return nil, err + } + return community.Images(), nil + }) + mediaServer.SetCommunityTokensReader(func(communityID string) ([]*protobuf.CommunityTokenMetadata, error) { + community, err := manager.GetByIDString(communityID) + if err != nil { + return nil, err + } + return community.CommunityTokensMetadata(), nil + }) + } + return manager, nil } diff --git a/server/handlers.go b/server/handlers.go index e5717d154..e0f48fd3d 100644 --- a/server/handlers.go +++ b/server/handlers.go @@ -14,9 +14,6 @@ import ( "strconv" "time" - "github.com/golang/protobuf/proto" - - "github.com/status-im/status-go/eth-node/types" "github.com/status-im/status-go/protocol/protobuf" "go.uber.org/zap" @@ -1000,7 +997,7 @@ func handleCommunityTokenImages(db *sql.DB, logger *zap.Logger) http.HandlerFunc } } -func handleCommunityDescriptionImagesPath(db *sql.DB, logger *zap.Logger) http.HandlerFunc { +func handleCommunityDescriptionImagesPath(db *sql.DB, getCommunityImages func(communityID string) (map[string]*protobuf.IdentityImage, error), logger *zap.Logger) http.HandlerFunc { if db == nil { return handleRequestDBMissing(logger) } @@ -1019,17 +1016,13 @@ func handleCommunityDescriptionImagesPath(db *sql.DB, logger *zap.Logger) http.H name = params["name"][0] } - err, communityDescription := getCommunityDescription(db, communityID, logger) + communityImages, err := getCommunityImages(communityID) if err != nil { return } - if communityDescription.Identity == nil { - logger.Error("no identity in community description", zap.String("community id", communityID)) - return - } var imagePayload []byte - for t, i := range communityDescription.Identity.Images { + for t, i := range communityImages { if t == name { imagePayload = i.Payload } @@ -1053,7 +1046,7 @@ func handleCommunityDescriptionImagesPath(db *sql.DB, logger *zap.Logger) http.H } } -func handleCommunityDescriptionTokenImagesPath(db *sql.DB, logger *zap.Logger) http.HandlerFunc { +func handleCommunityDescriptionTokenImagesPath(db *sql.DB, getCommunityTokens func(communityID string) ([]*protobuf.CommunityTokenMetadata, error), logger *zap.Logger) http.HandlerFunc { if db == nil { return handleRequestDBMissing(logger) } @@ -1073,13 +1066,13 @@ func handleCommunityDescriptionTokenImagesPath(db *sql.DB, logger *zap.Logger) h } symbol := params["symbol"][0] - err, communityDescription := getCommunityDescription(db, communityID, logger) + communityTokens, err := getCommunityTokens(communityID) if err != nil { return } var foundToken *protobuf.CommunityTokenMetadata - for _, m := range communityDescription.CommunityTokensMetadata { + for _, m := range communityTokens { if m.GetSymbol() == symbol { foundToken = m } @@ -1108,23 +1101,6 @@ func handleCommunityDescriptionTokenImagesPath(db *sql.DB, logger *zap.Logger) h } } -// getCommunityDescription returns the latest community description from the cache. -// NOTE: you should ensure preprocessDescription is called before this function. -func getCommunityDescription(db *sql.DB, communityID string, logger *zap.Logger) (error, *protobuf.CommunityDescription) { - var descriptionBytes []byte - err := db.QueryRow(`SELECT description FROM encrypted_community_description_cache WHERE community_id = ? ORDER BY clock DESC LIMIT 1`, types.Hex2Bytes(communityID)).Scan(&descriptionBytes) - if err != nil { - logger.Error("failed to find community description", zap.String("community id", communityID), zap.Error(err)) - return err, nil - } - communityDescription := new(protobuf.CommunityDescription) - err = proto.Unmarshal(descriptionBytes, communityDescription) - if err != nil { - logger.Error("failed to unmarshal community description", zap.String("community id", communityID), zap.Error(err)) - } - return err, communityDescription -} - func handleWalletCommunityImages(db *sql.DB, logger *zap.Logger) http.HandlerFunc { if db == nil { return handleRequestDBMissing(logger) diff --git a/server/server_media.go b/server/server_media.go index 793318acf..d03e41b2d 100644 --- a/server/server_media.go +++ b/server/server_media.go @@ -3,6 +3,7 @@ package server import ( "crypto/tls" "database/sql" + "errors" "net/url" "strconv" @@ -10,6 +11,7 @@ import ( "github.com/status-im/status-go/logutils" "github.com/status-im/status-go/multiaccounts" "github.com/status-im/status-go/protocol/common" + "github.com/status-im/status-go/protocol/protobuf" "github.com/status-im/status-go/services/wallet/thirdparty" "github.com/status-im/status-go/signal" ) @@ -25,10 +27,12 @@ func WithMediaServerDisableTLS(disableTLS bool) MediaServerOption { type MediaServer struct { Server - db *sql.DB - downloader *ipfs.Downloader - multiaccountsDB *multiaccounts.Database - walletDB *sql.DB + db *sql.DB + downloader *ipfs.Downloader + multiaccountsDB *multiaccounts.Database + walletDB *sql.DB + getCommunityImagesReader func(communityID string) (map[string]*protobuf.IdentityImage, error) + getCommunityTokenReader func(communityID string) ([]*protobuf.CommunityTokenMetadata, error) // disableTLS controls whether the media server uses HTTP instead of HTTPS. // Set to true to avoid TLS certificate issues with react-native-fast-image @@ -89,8 +93,8 @@ func NewMediaServer(db *sql.DB, downloader *ipfs.Downloader, multiaccountsDB *mu LinkPreviewFaviconPath: handleLinkPreviewFavicon(s.db, s.logger), StatusLinkPreviewThumbnailPath: handleStatusLinkPreviewThumbnail(s.db, s.logger), communityTokenImagesPath: handleCommunityTokenImages(s.db, s.logger), - communityDescriptionImagesPath: handleCommunityDescriptionImagesPath(s.db, s.logger), - communityDescriptionTokenImagesPath: handleCommunityDescriptionTokenImagesPath(s.db, s.logger), + communityDescriptionImagesPath: handleCommunityDescriptionImagesPath(s.db, s.getCommunityImage, s.logger), + communityDescriptionTokenImagesPath: handleCommunityDescriptionTokenImagesPath(s.db, s.getCommunityTokens, s.logger), walletCommunityImagesPath: handleWalletCommunityImages(s.walletDB, s.logger), walletCollectionImagesPath: handleWalletCollectionImages(s.walletDB, s.logger), walletCollectibleImagesPath: handleWalletCollectibleImages(s.walletDB, s.logger), @@ -106,6 +110,28 @@ func (s *MediaServer) MakeBaseURL() *url.URL { } } +func (s *MediaServer) SetCommunityImageReader(getFunc func(communityID string) (map[string]*protobuf.IdentityImage, error)) { + s.getCommunityImagesReader = getFunc +} + +func (s *MediaServer) getCommunityImage(communityID string) (map[string]*protobuf.IdentityImage, error) { + if s.getCommunityImagesReader == nil { + return nil, errors.New("community image reader not set") + } + return s.getCommunityImagesReader(communityID) +} + +func (s *MediaServer) SetCommunityTokensReader(getFunc func(communityID string) ([]*protobuf.CommunityTokenMetadata, error)) { + s.getCommunityTokenReader = getFunc +} + +func (s *MediaServer) getCommunityTokens(communityID string) ([]*protobuf.CommunityTokenMetadata, error) { + if s.getCommunityTokenReader == nil { + return nil, errors.New("community token reader not set") + } + return s.getCommunityTokenReader(communityID) +} + func (s *MediaServer) MakeImageServerURL() string { u := s.MakeBaseURL() u.Path = basePath + "/" diff --git a/server/server_media_interface.go b/server/server_media_interface.go index a62d5a165..cd9cbab6e 100644 --- a/server/server_media_interface.go +++ b/server/server_media_interface.go @@ -1,6 +1,10 @@ package server +import "github.com/status-im/status-go/protocol/protobuf" + type MediaServerInterface interface { MakeCommunityDescriptionTokenImageURL(communityID, symbol string) string MakeCommunityImageURL(communityID, name string) string + SetCommunityImageReader(func(communityID string) (map[string]*protobuf.IdentityImage, error)) + SetCommunityTokensReader(func(communityID string) ([]*protobuf.CommunityTokenMetadata, error)) }