chore(communities)_: reject outdated community descriptions
Prevent the inclusion of CommunityDescription with an outdated clock in MessengerResponse to avoid false-positives in tests and reduce redundant data exchange between status-go and clients.
This commit is contained in:
parent
dbed69d155
commit
27934a4e1f
|
@ -1130,11 +1130,9 @@ func (o *Community) UpdateCommunityDescription(description *protobuf.CommunityDe
|
|||
return nil, err
|
||||
}
|
||||
|
||||
response := o.emptyCommunityChanges()
|
||||
|
||||
// Enables processing of identical clocks. Identical descriptions may be reprocessed upon subsequent receipt of the previously missing encryption key.
|
||||
if description.Clock < o.config.CommunityDescription.Clock {
|
||||
return response, nil
|
||||
return nil, ErrInvalidCommunityDescriptionClockOutdated
|
||||
}
|
||||
|
||||
originCommunity := o.CreateDeepCopy()
|
||||
|
@ -1146,6 +1144,8 @@ func (o *Community) UpdateCommunityDescription(description *protobuf.CommunityDe
|
|||
o.setControlNode(newControlNode)
|
||||
}
|
||||
|
||||
response := o.emptyCommunityChanges()
|
||||
|
||||
// We only calculate changes if we joined/spectated the community or we requested access, otherwise not interested
|
||||
if o.config.Joined || o.config.Spectated || o.config.RequestedToJoinAt > 0 {
|
||||
response = EvaluateCommunityChanges(originCommunity, o)
|
||||
|
|
|
@ -567,8 +567,8 @@ func (s *CommunitySuite) TestHandleCommunityDescription() {
|
|||
name: "updated version but lower clock",
|
||||
description: s.oldCommunityDescription,
|
||||
signer: signer,
|
||||
changes: buildChanges,
|
||||
err: nil,
|
||||
changes: func(c *Community) *CommunityChanges { return nil },
|
||||
err: ErrInvalidCommunityDescriptionClockOutdated,
|
||||
},
|
||||
{
|
||||
name: "removed member from org",
|
||||
|
|
|
@ -12,6 +12,7 @@ var ErrChatAlreadyExists = errors.New("chat already exists")
|
|||
var ErrCategoryAlreadyExists = errors.New("category already exists")
|
||||
var ErrCantRequestAccess = errors.New("can't request access")
|
||||
var ErrInvalidCommunityDescription = errors.New("invalid community description")
|
||||
var ErrInvalidCommunityDescriptionClockOutdated = errors.New("invalid community description outdated clock")
|
||||
var ErrInvalidCommunityDescriptionNoOrgPermissions = errors.New("invalid community description no org permissions")
|
||||
var ErrInvalidCommunityDescriptionNoChatPermissions = errors.New("invalid community description no chat permissions")
|
||||
var ErrInvalidCommunityDescriptionUnknownChatAccess = errors.New("invalid community description unknown chat access")
|
||||
|
|
|
@ -4554,3 +4554,66 @@ func (s *MessengerCommunitiesSuite) TestAliceDidNotProcessOutdatedCommunityReque
|
|||
err = s.alice.HandleCommunityRequestToJoinResponse(state, requestToJoinResponse, nil)
|
||||
s.Require().NoError(err)
|
||||
}
|
||||
|
||||
func (s *MessengerCommunitiesSuite) TestIgnoreOutdatedCommunityDescription() {
|
||||
community, _ := s.createCommunity()
|
||||
wrappedDescription1, err := community.ToProtocolMessageBytes()
|
||||
s.Require().NoError(err)
|
||||
signer, description1, err := communities.UnwrapCommunityDescriptionMessage(wrappedDescription1)
|
||||
s.Require().NoError(err)
|
||||
|
||||
_, err = community.AddMember(&s.alice.identity.PublicKey, []protobuf.CommunityMember_Roles{})
|
||||
s.Require().NoError(err)
|
||||
wrappedDescription2, err := community.ToProtocolMessageBytes()
|
||||
s.Require().NoError(err)
|
||||
_, description2, err := communities.UnwrapCommunityDescriptionMessage(wrappedDescription2)
|
||||
s.Require().NoError(err)
|
||||
|
||||
_, err = community.AddMember(&s.bob.identity.PublicKey, []protobuf.CommunityMember_Roles{})
|
||||
s.Require().NoError(err)
|
||||
wrappedDescription3, err := community.ToProtocolMessageBytes()
|
||||
s.Require().NoError(err)
|
||||
_, description3, err := communities.UnwrapCommunityDescriptionMessage(wrappedDescription3)
|
||||
s.Require().NoError(err)
|
||||
|
||||
s.Require().Less(description1.Clock, description2.Clock)
|
||||
s.Require().Less(description2.Clock, description3.Clock)
|
||||
|
||||
// Handle first community description
|
||||
{
|
||||
messageState := s.bob.buildMessageState()
|
||||
err = s.bob.handleCommunityDescription(messageState, signer, description1, wrappedDescription1, nil, nil)
|
||||
s.Require().NoError(err)
|
||||
s.Require().Len(messageState.Response.Communities(), 1)
|
||||
s.Require().Equal(description1.Clock, messageState.Response.Communities()[0].Clock())
|
||||
}
|
||||
|
||||
// Handle third community description
|
||||
{
|
||||
messageState := s.bob.buildMessageState()
|
||||
err = s.bob.handleCommunityDescription(messageState, signer, description3, wrappedDescription3, nil, nil)
|
||||
s.Require().NoError(err)
|
||||
s.Require().Len(messageState.Response.Communities(), 1)
|
||||
s.Require().Equal(description3.Clock, messageState.Response.Communities()[0].Clock())
|
||||
|
||||
communityFromDB, err := s.bob.communitiesManager.GetByID(community.ID())
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal(description3.Clock, communityFromDB.Clock())
|
||||
s.Require().Len(communityFromDB.Members(), 3)
|
||||
}
|
||||
|
||||
// Handle second (out of order) community description
|
||||
// It should be ignored
|
||||
{
|
||||
messageState := s.bob.buildMessageState()
|
||||
err = s.bob.handleCommunityDescription(messageState, signer, description2, wrappedDescription2, nil, nil)
|
||||
s.Require().Len(messageState.Response.Communities(), 0)
|
||||
s.Require().Len(messageState.Response.CommunityChanges, 0)
|
||||
s.Require().ErrorIs(err, communities.ErrInvalidCommunityDescriptionClockOutdated)
|
||||
|
||||
communityFromDB, err := s.bob.communitiesManager.GetByID(community.ID())
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal(description3.Clock, communityFromDB.Clock())
|
||||
s.Require().Len(communityFromDB.Members(), 3)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3693,7 +3693,8 @@ func (m *Messenger) handleSyncInstallationCommunity(messageState *ReceivedMessag
|
|||
|
||||
// TODO: handle shard
|
||||
err = m.handleCommunityDescription(messageState, signer, &cd, syncCommunity.Description, signer, nil)
|
||||
if err != nil {
|
||||
// Even if the Description is outdated we should proceed in order to sync settings and joined state
|
||||
if err != nil && err != communities.ErrInvalidCommunityDescriptionClockOutdated {
|
||||
logger.Debug("m.handleCommunityDescription error", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue