fix: stop sending channels members over the wire

fixes: status-im/status-desktop#12114
This commit is contained in:
Patryk Osmaczko 2023-09-25 13:26:17 +02:00 committed by osmaczko
parent 2697c07705
commit 475036e9f2
2 changed files with 142 additions and 15 deletions

View File

@ -1290,9 +1290,48 @@ func (o *Community) toProtocolMessageBytes() ([]byte, error) {
func (o *Community) ToProtocolMessageBytes() ([]byte, error) {
o.mutex.Lock()
defer o.mutex.Unlock()
// This is only workaround to lower the size of the message that goes over the wire,
// see https://github.com/status-im/status-desktop/issues/12188
if o.IsControlNode() {
clone := o.CreateDeepCopy()
clone.DehydrateChannelsMembers()
return clone.toProtocolMessageBytes()
}
return o.toProtocolMessageBytes()
}
func (o *Community) DehydrateChannelsMembers() {
// To save space, we don't attach members for channels without permissions,
// otherwise the message will hit waku msg size limit.
for channelID, channel := range o.chats() {
if !o.ChannelHasTokenPermissions(o.IDString() + channelID) {
channel.Members = map[string]*protobuf.CommunityMember{} // clean members
}
}
}
func HydrateChannelsMembers(communityID string, description *protobuf.CommunityDescription) {
channelHasTokenPermissions := func(channelID string) bool {
for _, tokenPermission := range description.TokenPermissions {
if includes(tokenPermission.ChatIds, communityID+channelID) {
return true
}
}
return false
}
for channelID, channel := range description.Chats {
if !channelHasTokenPermissions(channelID) {
channel.Members = make(map[string]*protobuf.CommunityMember)
for pubKey, member := range description.Members {
channel.Members[pubKey] = member
}
}
}
}
func (o *Community) Chats() map[string]*protobuf.CommunityChat {
// Why are we checking here for nil, it should be the responsibility of the caller
if o == nil {

View File

@ -489,7 +489,19 @@ func (m *Manager) publish(subscription *Subscription) {
}
func (m *Manager) All() ([]*Community, error) {
return m.persistence.AllCommunities(&m.identity.PublicKey)
communities, err := m.persistence.AllCommunities(&m.identity.PublicKey)
if err != nil {
return nil, err
}
for _, c := range communities {
err = initializeCommunity(c)
if err != nil {
return nil, err
}
}
return communities, nil
}
type KnownCommunitiesResponse struct {
@ -525,23 +537,83 @@ func (m *Manager) GetStoredDescriptionForCommunities(communityIDs []types.HexByt
}
func (m *Manager) Joined() ([]*Community, error) {
return m.persistence.JoinedCommunities(&m.identity.PublicKey)
communities, err := m.persistence.JoinedCommunities(&m.identity.PublicKey)
if err != nil {
return nil, err
}
for _, c := range communities {
err = initializeCommunity(c)
if err != nil {
return nil, err
}
}
return communities, nil
}
func (m *Manager) Spectated() ([]*Community, error) {
return m.persistence.SpectatedCommunities(&m.identity.PublicKey)
communities, err := m.persistence.SpectatedCommunities(&m.identity.PublicKey)
if err != nil {
return nil, err
}
for _, c := range communities {
err = initializeCommunity(c)
if err != nil {
return nil, err
}
}
return communities, nil
}
func (m *Manager) JoinedAndPendingCommunitiesWithRequests() ([]*Community, error) {
return m.persistence.JoinedAndPendingCommunitiesWithRequests(&m.identity.PublicKey)
communities, err := m.persistence.JoinedAndPendingCommunitiesWithRequests(&m.identity.PublicKey)
if err != nil {
return nil, err
}
for _, c := range communities {
err = initializeCommunity(c)
if err != nil {
return nil, err
}
}
return communities, nil
}
func (m *Manager) DeletedCommunities() ([]*Community, error) {
return m.persistence.DeletedCommunities(&m.identity.PublicKey)
communities, err := m.persistence.DeletedCommunities(&m.identity.PublicKey)
if err != nil {
return nil, err
}
for _, c := range communities {
err = initializeCommunity(c)
if err != nil {
return nil, err
}
}
return communities, nil
}
func (m *Manager) ControlledCommunities() ([]*Community, error) {
return m.persistence.CommunitiesWithPrivateKey(&m.identity.PublicKey)
communities, err := m.persistence.CommunitiesWithPrivateKey(&m.identity.PublicKey)
if err != nil {
return nil, err
}
for _, c := range communities {
err = initializeCommunity(c)
if err != nil {
return nil, err
}
}
return communities, nil
}
// CreateCommunity takes a description, generates an ID for it, saves it and return it
@ -953,7 +1025,7 @@ func (m *Manager) ExportCommunity(id types.HexBytes) (*ecdsa.PrivateKey, error)
func (m *Manager) ImportCommunity(key *ecdsa.PrivateKey) (*Community, error) {
communityID := crypto.CompressPubkey(&key.PublicKey)
community, err := m.persistence.GetByID(&m.identity.PublicKey, communityID)
community, err := m.GetByID(communityID)
if err != nil {
return nil, err
}
@ -1238,11 +1310,14 @@ func (m *Manager) HandleCommunityDescriptionMessage(signer *ecdsa.PublicKey, des
id := crypto.CompressPubkey(signer)
community, err := m.persistence.GetByID(&m.identity.PublicKey, id)
community, err := m.GetByID(id)
if err != nil {
return nil, err
}
// Workaround for https://github.com/status-im/status-desktop/issues/12188
HydrateChannelsMembers(types.EncodeHex(id), description)
if community == nil {
config := Config{
CommunityDescription: description,
@ -1405,7 +1480,7 @@ func (m *Manager) HandleCommunityEventsMessage(signer *ecdsa.PublicKey, message
return nil, err
}
community, err := m.persistence.GetByID(&m.identity.PublicKey, eventsMessage.CommunityID)
community, err := m.GetByID(eventsMessage.CommunityID)
if err != nil {
return nil, err
}
@ -1481,7 +1556,7 @@ func (m *Manager) HandleCommunityEventsMessageRejected(signer *ecdsa.PublicKey,
}
id := crypto.CompressPubkey(signer)
community, err := m.persistence.GetByID(&m.identity.PublicKey, id)
community, err := m.GetByID(id)
if err != nil {
return nil, err
}
@ -2025,7 +2100,7 @@ func (m *Manager) isUserRejectedFromCommunity(signer *ecdsa.PublicKey, community
}
func (m *Manager) HandleCommunityCancelRequestToJoin(signer *ecdsa.PublicKey, request *protobuf.CommunityCancelRequestToJoin) (*RequestToJoin, error) {
community, err := m.persistence.GetByID(&m.identity.PublicKey, request.CommunityId)
community, err := m.GetByID(request.CommunityId)
if err != nil {
return nil, err
}
@ -2201,7 +2276,7 @@ func (m *Manager) HandleCommunityRequestToJoin(signer *ecdsa.PublicKey, receiver
}
func (m *Manager) HandleCommunityEditSharedAddresses(signer *ecdsa.PublicKey, request *protobuf.CommunityEditSharedAddresses) error {
community, err := m.persistence.GetByID(&m.identity.PublicKey, request.CommunityId)
community, err := m.GetByID(request.CommunityId)
if err != nil {
return err
}
@ -2752,7 +2827,7 @@ type CheckAllChannelsPermissionsResponse struct {
func (m *Manager) HandleCommunityRequestToJoinResponse(signer *ecdsa.PublicKey, request *protobuf.CommunityRequestToJoinResponse) (*RequestToJoin, error) {
pkString := common.PubkeyToHex(&m.identity.PublicKey)
community, err := m.persistence.GetByID(&m.identity.PublicKey, request.CommunityId)
community, err := m.GetByID(request.CommunityId)
if err != nil {
return nil, err
}
@ -3113,6 +3188,19 @@ func (m *Manager) BanUserFromCommunity(request *requests.BanUserFromCommunity) (
return community, nil
}
// Apply events to raw community
func initializeCommunity(community *Community) error {
err := community.updateCommunityDescriptionByEvents()
if err != nil {
return err
}
// Workaround for https://github.com/status-im/status-desktop/issues/12188
HydrateChannelsMembers(community.IDString(), community.config.CommunityDescription)
return nil
}
func (m *Manager) GetByID(id []byte) (*Community, error) {
community, err := m.persistence.GetByID(&m.identity.PublicKey, id)
if err != nil {
@ -3122,7 +3210,7 @@ func (m *Manager) GetByID(id []byte) (*Community, error) {
return nil, nil
}
err = community.updateCommunityDescriptionByEvents()
err = initializeCommunity(community)
if err != nil {
return nil, err
}
@ -3162,7 +3250,7 @@ func (m *Manager) SaveRequestToJoinAndCommunity(requestToJoin *RequestToJoin, co
}
func (m *Manager) CreateRequestToJoin(requester *ecdsa.PublicKey, request *requests.RequestToJoinCommunity) (*Community, *RequestToJoin, error) {
community, err := m.persistence.GetByID(&m.identity.PublicKey, request.CommunityID)
community, err := m.GetByID(request.CommunityID)
if err != nil {
return nil, nil, err
}