Handle a few edge cases in contact requests

This commit is contained in:
Andrea Maria Piana 2023-02-02 18:12:20 +00:00
parent 7360e07224
commit 7523ff1104
13 changed files with 920 additions and 242 deletions

View File

@ -325,6 +325,8 @@ func (c *Chat) NextClockAndTimestamp(timesource common.TimeSource) (uint64, uint
} else {
clock = clock + 1
}
c.LastClockValue = clock
return clock, timestamp
}

View File

@ -13,6 +13,7 @@ import (
"github.com/status-im/status-go/protocol/identity"
"github.com/status-im/status-go/protocol/identity/alias"
"github.com/status-im/status-go/protocol/identity/identicon"
"github.com/status-im/status-go/protocol/protobuf"
"github.com/status-im/status-go/protocol/verification"
)
@ -22,6 +23,9 @@ const (
ContactRequestStateNone ContactRequestState = iota
ContactRequestStateMutual
ContactRequestStateSent
// Received is a confusing state, we should use
// sent for both, since they are now stored in different
// states
ContactRequestStateReceived
ContactRequestStateDismissed
)
@ -187,9 +191,14 @@ func (c *Contact) mutual() bool {
return c.added() && c.hasAddedUs()
}
func (c *Contact) dismissed() bool {
return c.ContactRequestLocalState == ContactRequestStateDismissed
}
type ContactRequestProcessingResponse struct {
processed bool
newContactRequestReceived bool
sendBackState bool
}
func (c *Contact) ContactRequestSent(clock uint64) ContactRequestProcessingResponse {
@ -243,28 +252,35 @@ func (c *Contact) DismissContactRequest(clock uint64) ContactRequestProcessingRe
// Remote actions
func (c *Contact) ContactRequestRetracted(clock uint64) ContactRequestProcessingResponse {
func (c *Contact) contactRequestRetracted(clock uint64, r ContactRequestProcessingResponse) ContactRequestProcessingResponse {
if clock <= c.ContactRequestRemoteClock {
return ContactRequestProcessingResponse{}
return r
}
// This is a symmetric action, we set both local & remote clock
// since we want everything before this point discarded, regardless
// the side it was sent from
c.ContactRequestRemoteClock = clock
c.ContactRequestRemoteState = ContactRequestStateNone
// the side it was sent from. The only exception is when the contact
// request has been explicitly dismissed, in which case we don't
// change state
if c.ContactRequestLocalState != ContactRequestStateDismissed {
c.ContactRequestLocalClock = clock
c.ContactRequestLocalState = ContactRequestStateNone
return ContactRequestProcessingResponse{processed: true}
}
c.ContactRequestRemoteClock = clock
c.ContactRequestRemoteState = ContactRequestStateNone
r.processed = true
return r
}
func (c *Contact) ContactRequestReceived(clock uint64) ContactRequestProcessingResponse {
func (c *Contact) ContactRequestRetracted(clock uint64) ContactRequestProcessingResponse {
return c.contactRequestRetracted(clock, ContactRequestProcessingResponse{})
}
func (c *Contact) contactRequestReceived(clock uint64, r ContactRequestProcessingResponse) ContactRequestProcessingResponse {
if clock <= c.ContactRequestRemoteClock {
return ContactRequestProcessingResponse{}
return r
}
r := ContactRequestProcessingResponse{processed: true}
r.processed = true
c.ContactRequestRemoteClock = clock
switch c.ContactRequestRemoteState {
case ContactRequestStateNone:
@ -275,6 +291,10 @@ func (c *Contact) ContactRequestReceived(clock uint64) ContactRequestProcessingR
return r
}
func (c *Contact) ContactRequestReceived(clock uint64) ContactRequestProcessingResponse {
return c.contactRequestReceived(clock, ContactRequestProcessingResponse{})
}
func (c *Contact) ContactRequestAccepted(clock uint64) ContactRequestProcessingResponse {
if clock <= c.ContactRequestRemoteClock {
return ContactRequestProcessingResponse{}
@ -383,3 +403,56 @@ func (c *Contact) MarshalJSON() ([]byte, error) {
return json.Marshal(item)
}
// ContactRequestPropagatedStateReceived handles the propagation of state from
// the other end.
func (c *Contact) ContactRequestPropagatedStateReceived(state *protobuf.ContactRequestPropagatedState) ContactRequestProcessingResponse {
// It's inverted, as their local states is our remote state
expectedLocalState := ContactRequestState(state.RemoteState)
expectedLocalClock := state.RemoteClock
remoteState := ContactRequestState(state.LocalState)
remoteClock := state.LocalClock
response := ContactRequestProcessingResponse{}
// If we notice that the state is not consistent, and their clock is
// outdated, we send back the state so they can catch up.
if expectedLocalClock < c.ContactRequestLocalClock && expectedLocalState != c.ContactRequestLocalState {
response.processed = true
response.sendBackState = true
}
// If they expect our state to be more up-to-date, we only
// trust it if the state is set to None, in this case we can trust
// it, since a retraction can be initiated by both parties
if expectedLocalClock > c.ContactRequestLocalClock && c.ContactRequestLocalState != ContactRequestStateDismissed && expectedLocalState == ContactRequestStateNone {
response.processed = true
c.ContactRequestLocalClock = expectedLocalClock
c.ContactRequestLocalState = ContactRequestStateNone
// We set they remote state, as this was an implicit retraction
// potentially
c.ContactRequestRemoteState = ContactRequestStateNone
}
// We always trust this
if remoteClock > c.ContactRequestRemoteClock {
if remoteState == ContactRequestStateSent {
response = c.contactRequestReceived(remoteClock, response)
} else if remoteState == ContactRequestStateNone {
response = c.contactRequestRetracted(remoteClock, response)
}
}
return response
}
func (c *Contact) ContactRequestPropagatedState() *protobuf.ContactRequestPropagatedState {
return &protobuf.ContactRequestPropagatedState{
LocalClock: c.ContactRequestLocalClock,
LocalState: uint64(c.ContactRequestLocalState),
RemoteClock: c.ContactRequestRemoteClock,
RemoteState: uint64(c.ContactRequestRemoteState),
}
}

View File

@ -10,6 +10,7 @@ import (
"github.com/status-im/status-go/eth-node/crypto"
"github.com/status-im/status-go/protocol/common"
"github.com/status-im/status-go/protocol/protobuf"
)
type contactTest struct {
@ -381,7 +382,7 @@ func TestContactContactRequestRetracted(t *testing.T) {
{
actualLocalState: ContactRequestStateDismissed,
actualRemoteState: ContactRequestStateNone,
expectedLocalState: ContactRequestStateNone,
expectedLocalState: ContactRequestStateDismissed,
expectedRemoteState: ContactRequestStateNone,
expectedAdded: false,
expectedHasAddedUs: false,
@ -390,7 +391,7 @@ func TestContactContactRequestRetracted(t *testing.T) {
{
actualLocalState: ContactRequestStateDismissed,
actualRemoteState: ContactRequestStateReceived,
expectedLocalState: ContactRequestStateNone,
expectedLocalState: ContactRequestStateDismissed,
expectedRemoteState: ContactRequestStateNone,
expectedAdded: false,
expectedHasAddedUs: false,
@ -559,3 +560,152 @@ func TestMarshalContactJSON(t *testing.T) {
require.True(t, strings.Contains(string(encodedContact), "compressedKey\":\"zQ"))
}
func TestContactContactRequestPropagatedStateReceivedOutOfDateLocalStateOnTheirSide(t *testing.T) {
// We receive a message with expected contact request state != our state
// and clock < our clock, we ping back the user to reach consistency
c := &Contact{}
c.ContactRequestLocalState = ContactRequestStateSent
c.ContactRequestLocalClock = 1
result := c.ContactRequestPropagatedStateReceived(
&protobuf.ContactRequestPropagatedState{
RemoteState: uint64(ContactRequestStateNone),
RemoteClock: 0,
LocalState: uint64(ContactRequestStateNone),
LocalClock: 1,
},
)
require.True(t, result.sendBackState)
// if the state is the same, it should not send back a message
c = &Contact{}
c.ContactRequestLocalState = ContactRequestStateNone
c.ContactRequestLocalClock = 1
result = c.ContactRequestPropagatedStateReceived(
&protobuf.ContactRequestPropagatedState{
RemoteState: uint64(ContactRequestStateNone),
RemoteClock: 0,
LocalState: uint64(ContactRequestStateNone),
LocalClock: 1,
},
)
require.False(t, result.sendBackState)
// If the clock is the same, it should not send back a message
c = &Contact{}
c.ContactRequestLocalState = ContactRequestStateSent
c.ContactRequestLocalClock = 1
result = c.ContactRequestPropagatedStateReceived(
&protobuf.ContactRequestPropagatedState{
RemoteState: uint64(ContactRequestStateNone),
RemoteClock: 1,
LocalState: uint64(ContactRequestStateNone),
LocalClock: 1,
},
)
require.False(t, result.sendBackState)
}
func TestContactContactRequestPropagatedStateReceivedOutOfDateLocalStateOnOurSide(t *testing.T) {
// We receive a message with expected contact request state == none
// and clock > our clock. We consider this a retraction, unless we are in the dismissed state, since that should be only changed by a trusted device
c := &Contact{}
c.ContactRequestLocalState = ContactRequestStateSent
c.ContactRequestLocalClock = 1
c.ContactRequestPropagatedStateReceived(
&protobuf.ContactRequestPropagatedState{
RemoteState: uint64(ContactRequestStateNone),
RemoteClock: 2,
LocalState: uint64(ContactRequestStateNone),
LocalClock: 1,
},
)
require.False(t, c.added())
// But if it's dismissed, we don't change it
c = &Contact{}
c.ContactRequestLocalState = ContactRequestStateDismissed
c.ContactRequestLocalClock = 1
c.ContactRequestPropagatedStateReceived(
&protobuf.ContactRequestPropagatedState{
RemoteState: uint64(ContactRequestStateNone),
RemoteClock: 1,
LocalState: uint64(ContactRequestStateNone),
LocalClock: 2,
},
)
require.False(t, c.added())
require.True(t, c.dismissed())
// or if it's lower clock
c = &Contact{}
c.ContactRequestLocalState = ContactRequestStateSent
c.ContactRequestLocalClock = 1
c.ContactRequestPropagatedStateReceived(
&protobuf.ContactRequestPropagatedState{
RemoteState: uint64(ContactRequestStateNone),
RemoteClock: 1,
LocalState: uint64(ContactRequestStateNone),
LocalClock: 0,
},
)
require.True(t, c.added())
}
func TestContactContactRequestPropagatedStateReceivedOutOfDateRemoteState(t *testing.T) {
// We receive a message with newer remote state, we process it as we would for a normal contact request
c := &Contact{}
c.ContactRequestLocalState = ContactRequestStateSent
c.ContactRequestLocalClock = 1
c.ContactRequestPropagatedStateReceived(
&protobuf.ContactRequestPropagatedState{
RemoteState: uint64(ContactRequestStateSent),
RemoteClock: 1,
LocalState: uint64(ContactRequestStateSent),
LocalClock: 1,
},
)
require.True(t, c.added())
require.True(t, c.mutual())
// and retraction
c = &Contact{}
c.ContactRequestLocalState = ContactRequestStateSent
c.ContactRequestLocalClock = 1
c.ContactRequestRemoteState = ContactRequestStateReceived
c.ContactRequestRemoteClock = 1
c.ContactRequestPropagatedStateReceived(
&protobuf.ContactRequestPropagatedState{
RemoteState: uint64(ContactRequestStateSent),
RemoteClock: 1,
LocalState: uint64(ContactRequestStateNone),
LocalClock: 2,
},
)
require.False(t, c.added())
require.False(t, c.hasAddedUs())
require.False(t, c.mutual())
}

View File

@ -1992,6 +1992,11 @@ func (m *Messenger) sendChatMessage(ctx context.Context, message *common.Message
return nil, err
}
err = m.addContactRequestPropagatedState(message)
if err != nil {
return nil, err
}
encodedMessage, err := m.encodeChatEntity(chat, message)
if err != nil {
return nil, err

View File

@ -1276,3 +1276,398 @@ func (s *MessengerContactRequestSuite) TestPairedDevicesRemoveContact() {
s.Require().Equal(ContactRequestStateNone, resp.Contacts[0].ContactRequestLocalState)
s.Require().Equal(ContactRequestStateNone, resp.Contacts[0].ContactRequestRemoteState)
}
// The scenario tested is as follow:
// 1) Alice sends a contact request to Bob
// 2) Bob accepts the contact request
// 3) Alice restores state on a different device
// 4) Alice sends a contact request to bob
// Bob will need to help Alice recover her state, since as far as he can see
// that's an already accepted contact request
func (s *MessengerContactRequestSuite) TestAliceRecoverStateSendContactRequest() {
// Alice sends a contact request to bob
alice1 := s.m
bob := s.newMessenger(s.shh)
_, err := bob.Start()
s.Require().NoError(err)
bobID := types.EncodeHex(crypto.FromECDSAPub(&bob.identity.PublicKey))
myID := types.EncodeHex(crypto.FromECDSAPub(&alice1.identity.PublicKey))
request := &requests.AddContact{
ID: types.Hex2Bytes(bobID),
}
_, err = alice1.AddContact(context.Background(), request)
s.Require().NoError(err)
// Wait for the message to reach its destination
resp, err := WaitOnMessengerResponse(
bob,
func(r *MessengerResponse) bool {
return len(r.Contacts) > 0 && len(r.Messages()) > 0 && len(r.ActivityCenterNotifications()) > 0
},
"no messages",
)
// Check contact request has been received
s.Require().NoError(err)
// Check the contact state is correctly set
s.Require().Len(resp.Contacts, 1)
s.Require().Equal(ContactRequestStateReceived, resp.Contacts[0].ContactRequestRemoteState)
// Bob accepts the contact request
_, err = bob.AcceptLatestContactRequestForContact(context.Background(), &requests.AcceptLatestContactRequestForContact{ID: types.Hex2Bytes(myID)})
s.Require().NoError(err)
// Alice receives the accepted confirmation
resp, err = WaitOnMessengerResponse(
alice1,
func(r *MessengerResponse) bool {
return len(r.Contacts) > 0
},
"no messages",
)
s.Require().NoError(err)
// Make sure we consider them a mutual contact, sender side
mutualContacts := alice1.MutualContacts()
s.Require().Len(mutualContacts, 1)
// Check the contact state is correctly set
s.Require().Len(resp.Contacts, 1)
s.Require().True(resp.Contacts[0].mutual())
// Alice resets her device
alice2, err := newMessengerWithKey(s.shh, s.m.identity, s.logger, nil)
s.Require().NoError(err)
_, err = alice2.Start()
s.Require().NoError(err)
// adds bob again to her device
request = &requests.AddContact{
ID: types.Hex2Bytes(bobID),
}
_, err = alice2.AddContact(context.Background(), request)
s.Require().NoError(err)
// Wait for the message to reach its destination
_, err = WaitOnMessengerResponse(
bob,
func(r *MessengerResponse) bool {
return len(r.Contacts) > 0 && len(r.Messages()) > 0 && len(r.ActivityCenterNotifications()) > 0
},
"no messages",
)
s.Require().NoError(err)
// Bob should be a mutual contact with alice, nothing has changed
s.Require().Len(bob.MutualContacts(), 1)
// Alice retrieves her messages, she should have been notified by
// dear bobby that they were contacts
resp, err = WaitOnMessengerResponse(
alice2,
func(r *MessengerResponse) bool {
return len(r.Contacts) > 0
},
"no messages",
)
s.Require().NoError(err)
s.Require().NotNil(resp)
s.Require().Len(resp.Contacts, 1)
// Check the contact state is correctly set
s.Require().True(resp.Contacts[0].mutual())
}
// The scenario tested is as follow:
// 1) Alice sends a contact request to Bob
// 2) Bob accepts the contact request
// 3) Alice restores state on a different device
// 4) Bob sends a message to alice
// Alice will show a contact request from bob
func (s *MessengerContactRequestSuite) TestAliceRecoverStateReceiveContactRequest() {
// Alice sends a contact request to bob
alice1 := s.m
bob := s.newMessenger(s.shh)
_, err := bob.Start()
s.Require().NoError(err)
bobID := types.EncodeHex(crypto.FromECDSAPub(&bob.identity.PublicKey))
myID := types.EncodeHex(crypto.FromECDSAPub(&alice1.identity.PublicKey))
request := &requests.AddContact{
ID: types.Hex2Bytes(bobID),
}
_, err = alice1.AddContact(context.Background(), request)
s.Require().NoError(err)
// Wait for the message to reach its destination
resp, err := WaitOnMessengerResponse(
bob,
func(r *MessengerResponse) bool {
return len(r.Contacts) > 0 && len(r.Messages()) > 0 && len(r.ActivityCenterNotifications()) > 0
},
"no messages",
)
// Check contact request has been received
s.Require().NoError(err)
// Check the contact state is correctly set
s.Require().Len(resp.Contacts, 1)
s.Require().Equal(ContactRequestStateReceived, resp.Contacts[0].ContactRequestRemoteState)
// Bob accepts the contact request
_, err = bob.AcceptLatestContactRequestForContact(context.Background(), &requests.AcceptLatestContactRequestForContact{ID: types.Hex2Bytes(myID)})
s.Require().NoError(err)
// Alice receives the accepted confirmation
resp, err = WaitOnMessengerResponse(
alice1,
func(r *MessengerResponse) bool {
return len(r.Contacts) > 0
},
"no messages",
)
s.Require().NoError(err)
// Make sure we consider them a mutual contact, sender side
mutualContacts := alice1.MutualContacts()
s.Require().Len(mutualContacts, 1)
// Check the contact state is correctly set
s.Require().Len(resp.Contacts, 1)
s.Require().True(resp.Contacts[0].mutual())
// Alice resets her device
alice2, err := newMessengerWithKey(s.shh, s.m.identity, s.logger, nil)
s.Require().NoError(err)
_, err = alice2.Start()
s.Require().NoError(err)
// We want to facilitate the discovery of the x3dh bundl here, since bob does not know about alice device
alice2Bundle, err := alice2.encryptor.GetBundle(alice2.identity)
s.Require().NoError(err)
_, err = bob.encryptor.ProcessPublicBundle(bob.identity, alice2Bundle)
s.Require().NoError(err)
// Bob sends a chat message to alice
var chat Chat
chats := bob.Chats()
for i, c := range chats {
if c.ID == alice1.myHexIdentity() && c.OneToOne() {
chat = *chats[i]
}
}
s.Require().NotNil(chat)
inputMessage := buildTestMessage(chat)
_, err = bob.SendChatMessage(context.Background(), inputMessage)
s.NoError(err)
// Alice retrieves the chat message, it should be
resp, err = WaitOnMessengerResponse(
alice2,
func(r *MessengerResponse) bool {
return len(r.ActivityCenterNotifications()) == 1
},
"no messages",
)
s.Require().NoError(err)
s.Require().NotNil(resp)
s.Require().Equal(ActivityCenterNotificationTypeContactRequest, resp.ActivityCenterNotifications()[0].Type)
s.Require().Len(resp.Contacts, 1)
// Check the contact state is correctly set
s.Require().Equal(ContactRequestStateNone, resp.Contacts[0].ContactRequestLocalState)
s.Require().Equal(ContactRequestStateReceived, resp.Contacts[0].ContactRequestRemoteState)
}
// The scenario tested is as follow:
// 1) Alice sends a contact request to Bob
// 2) Bob accepts the contact request
// 3) Bob goes offline
// 4) Alice retracts the contact request
// 5) Alice adds bob back to her contacts
// 6) Bob goes online, they receive 4 and 5 in the correct order
func (s *MessengerContactRequestSuite) TestAliceOfflineRetractsAndAddsCorrectOrder() {
// Alice sends a contact request to bob
alice1 := s.m
bob := s.newMessenger(s.shh)
_, err := bob.Start()
s.Require().NoError(err)
bobID := types.EncodeHex(crypto.FromECDSAPub(&bob.identity.PublicKey))
myID := types.EncodeHex(crypto.FromECDSAPub(&alice1.identity.PublicKey))
request := &requests.AddContact{
ID: types.Hex2Bytes(bobID),
}
_, err = alice1.AddContact(context.Background(), request)
s.Require().NoError(err)
// Wait for the message to reach its destination
resp, err := WaitOnMessengerResponse(
bob,
func(r *MessengerResponse) bool {
return len(r.Contacts) > 0 && len(r.Messages()) > 0 && len(r.ActivityCenterNotifications()) > 0
},
"no messages",
)
// Check contact request has been received
s.Require().NoError(err)
// Check the contact state is correctly set
s.Require().Len(resp.Contacts, 1)
s.Require().Equal(ContactRequestStateReceived, resp.Contacts[0].ContactRequestRemoteState)
// Bob accepts the contact request
_, err = bob.AcceptLatestContactRequestForContact(context.Background(), &requests.AcceptLatestContactRequestForContact{ID: types.Hex2Bytes(myID)})
s.Require().NoError(err)
// Alice receives the accepted confirmation
resp, err = WaitOnMessengerResponse(
alice1,
func(r *MessengerResponse) bool {
return len(r.Contacts) > 0
},
"no messages",
)
s.Require().NoError(err)
// Make sure we consider them a mutual contact, sender side
mutualContacts := alice1.MutualContacts()
s.Require().Len(mutualContacts, 1)
// Check the contact state is correctly set
s.Require().Len(resp.Contacts, 1)
s.Require().True(resp.Contacts[0].mutual())
_, err = alice1.RetractContactRequest(&requests.RetractContactRequest{ContactID: types.Hex2Bytes(bob.myHexIdentity())})
s.Require().NoError(err)
// adds bob again to her device
request = &requests.AddContact{
ID: types.Hex2Bytes(bobID),
}
_, err = alice1.AddContact(context.Background(), request)
s.Require().NoError(err)
// Wait for the message to reach its destination
_, err = WaitOnMessengerResponse(
bob,
func(r *MessengerResponse) bool {
return len(r.ActivityCenterNotifications()) > 0
},
"no messages",
)
s.Require().NoError(err)
}
// The scenario tested is as follow:
// 1) Alice sends a contact request to Bob
// 2) Bob accepts the contact request
// 3) Bob goes offline
// 4) Alice retracts the contact request
// 5) Alice adds bob back to her contacts
// 6) Bob goes online, they receive 4 and 5 in the wrong order
func (s *MessengerContactRequestSuite) TestAliceOfflineRetractsAndAddsWrongOrder() {
// Alice sends a contact request to bob
alice1 := s.m
bob := s.newMessenger(s.shh)
_, err := bob.Start()
s.Require().NoError(err)
bobID := types.EncodeHex(crypto.FromECDSAPub(&bob.identity.PublicKey))
myID := types.EncodeHex(crypto.FromECDSAPub(&alice1.identity.PublicKey))
request := &requests.AddContact{
ID: types.Hex2Bytes(bobID),
}
_, err = alice1.AddContact(context.Background(), request)
s.Require().NoError(err)
// Wait for the message to reach its destination
resp, err := WaitOnMessengerResponse(
bob,
func(r *MessengerResponse) bool {
return len(r.Contacts) > 0 && len(r.Messages()) > 0 && len(r.ActivityCenterNotifications()) > 0
},
"no messages",
)
// Check contact request has been received
s.Require().NoError(err)
// Check the contact state is correctly set
s.Require().Len(resp.Contacts, 1)
s.Require().Equal(ContactRequestStateReceived, resp.Contacts[0].ContactRequestRemoteState)
// Bob accepts the contact request
_, err = bob.AcceptLatestContactRequestForContact(context.Background(), &requests.AcceptLatestContactRequestForContact{ID: types.Hex2Bytes(myID)})
s.Require().NoError(err)
// Alice receives the accepted confirmation
resp, err = WaitOnMessengerResponse(
alice1,
func(r *MessengerResponse) bool {
return len(r.Contacts) > 0
},
"no messages",
)
s.Require().NoError(err)
// Make sure we consider them a mutual contact, sender side
mutualContacts := alice1.MutualContacts()
s.Require().Len(mutualContacts, 1)
// Check the contact state is correctly set
s.Require().Len(resp.Contacts, 1)
s.Require().True(resp.Contacts[0].mutual())
_, err = alice1.RetractContactRequest(&requests.RetractContactRequest{ContactID: types.Hex2Bytes(bob.myHexIdentity())})
s.Require().NoError(err)
// adds bob again to her device
request = &requests.AddContact{
ID: types.Hex2Bytes(bobID),
}
_, err = alice1.AddContact(context.Background(), request)
s.Require().NoError(err)
// Get alice perspective of bob
bobFromAlice := alice1.AddedContacts()[0]
// Get bob perspective of alice
aliceFromBob := bob.MutualContacts()[0]
s.Require().NotNil(bobFromAlice)
s.Require().NotNil(aliceFromBob)
// We can't simulate out-of-order messages easily, so we need to do
// things manually here
result := aliceFromBob.ContactRequestPropagatedStateReceived(bobFromAlice.ContactRequestPropagatedState())
s.Require().True(result.newContactRequestReceived)
}

View File

@ -745,6 +745,7 @@ func (m *Messenger) sendContactUpdate(ctx context.Context, chatID, displayName,
EnsName: ensName,
ProfileImage: profileImage,
ContactRequestClock: contact.ContactRequestLocalClock,
ContactRequestPropagatedState: contact.ContactRequestPropagatedState(),
}
encodedMessage, err := proto.Marshal(contactUpdate)
if err != nil {

View File

@ -732,6 +732,7 @@ func (m *Messenger) handleAcceptContactRequest(
originalRequest *common.Message,
message protobuf.AcceptContactRequest) (ContactRequestProcessingResponse, error) {
m.logger.Info("received contact request", zap.Uint64("clock-sent", message.Clock), zap.Uint64("current-clock", contact.ContactRequestRemoteClock), zap.Uint64("current-state", uint64(contact.ContactRequestRemoteState)))
if contact.ContactRequestRemoteClock > message.Clock {
m.logger.Info("not handling accept since clock lower")
return ContactRequestProcessingResponse{}, nil
@ -740,8 +741,6 @@ func (m *Messenger) handleAcceptContactRequest(
// The contact request accepted wasn't found, a reason for this might
// be that we sent a legacy contact request/contact-update, or another
// device has sent it, and we haven't synchronized it
// TODO(cammellos): This might want to show a notification if we haven't
// added the user to contacts already
if originalRequest == nil {
return contact.ContactRequestAccepted(message.Clock), nil
}
@ -817,14 +816,13 @@ func (m *Messenger) HandleAcceptContactRequest(state *ReceivedMessageState, mess
return nil
}
func (m *Messenger) HandleRetractContactRequest(state *ReceivedMessageState, message protobuf.RetractContactRequest) error {
contact := state.CurrentMessageState.Contact
func (m *Messenger) handleRetractContactRequest(contact *Contact, message protobuf.RetractContactRequest) error {
if contact.ID == m.myHexIdentity() {
m.logger.Debug("retraction coming from us, ignoring")
return nil
}
m.logger.Debug("handling retracted contact request", zap.Uint64("clock", message.Clock))
r := contact.ContactRequestRetracted(message.Clock)
if !r.processed {
m.logger.Info("not handling retract since clock lower")
@ -837,9 +835,18 @@ func (m *Messenger) HandleRetractContactRequest(state *ReceivedMessageState, mes
return err
}
state.ModifiedContacts.Store(contact.ID, true)
m.allContacts.Store(contact.ID, contact)
state.AllContacts.Store(contact.ID, contact)
return nil
}
func (m *Messenger) HandleRetractContactRequest(state *ReceivedMessageState, message protobuf.RetractContactRequest) error {
contact := state.CurrentMessageState.Contact
err := m.handleRetractContactRequest(contact, message)
if err != nil {
return err
}
state.ModifiedContacts.Store(contact.ID, true)
return nil
}
@ -869,6 +876,29 @@ func (m *Messenger) HandleContactUpdate(state *ReceivedMessageState, message pro
logger.Info("Handling contact update")
if message.ContactRequestPropagatedState != nil {
result := contact.ContactRequestPropagatedStateReceived(message.ContactRequestPropagatedState)
if result.sendBackState {
// This is a bit dangerous, since it might trigger a ping-pong of contact updates
// also it should backoff/debounce
_, err = m.sendContactUpdate(context.Background(), contact.ID, "", "", "", m.dispatchMessage)
if err != nil {
return err
}
}
if result.newContactRequestReceived {
err = m.createContactRequestNotification(contact, state, nil)
if err != nil {
return err
}
}
state.ModifiedContacts.Store(contact.ID, true)
state.AllContacts.Store(contact.ID, contact)
}
if contact.LastUpdated < message.Clock {
logger.Info("Updating contact")
if contact.EnsName != message.EnsName {
@ -1675,6 +1705,27 @@ func (m *Messenger) HandleChatMessage(state *ReceivedMessageState) error {
contact := state.CurrentMessageState.Contact
// If we receive some propagated state from someone who's not
// our paired device, we handle it
if receivedMessage.ContactRequestPropagatedState != nil && !isSyncMessage {
result := contact.ContactRequestPropagatedStateReceived(receivedMessage.ContactRequestPropagatedState)
if result.sendBackState {
_, err = m.sendContactUpdate(context.Background(), contact.ID, "", "", "", m.dispatchMessage)
if err != nil {
return err
}
}
if result.newContactRequestReceived {
err = m.createContactRequestNotification(contact, state, receivedMessage)
if err != nil {
return err
}
}
state.ModifiedContacts.Store(contact.ID, true)
state.AllContacts.Store(contact.ID, contact)
}
if receivedMessage.ContentType == protobuf.ChatMessage_CONTACT_REQUEST && chat.OneToOne() {
chatContact := contact
@ -1749,11 +1800,6 @@ func (m *Messenger) HandleChatMessage(state *ReceivedMessageState) error {
}
}
// If the chat is not active, create a notification in the center
if !receivedMessage.Deleted && chat.OneToOne() && !chat.Active && receivedMessage.ContentType != protobuf.ChatMessage_CONTACT_REQUEST {
m.createMessageNotification(chat, state)
}
// Set in the modified maps chat
state.Response.AddChat(chat)
// TODO(samyoul) remove storing of an updated reference pointer?

View File

@ -326,3 +326,21 @@ func (m *Messenger) applyDeleteForMeMessage(messageDeletes []*DeleteForMeMessage
return nil
}
func (m *Messenger) addContactRequestPropagatedState(message *common.Message) error {
chat, ok := m.allChats.Load(message.LocalChatID)
if !ok {
return ErrChatNotFound
}
if !chat.OneToOne() {
return nil
}
contact, err := m.BuildContact(chat.ID)
if err != nil {
return err
}
message.ContactRequestPropagatedState = contact.ContactRequestPropagatedState()
return nil
}

View File

@ -1558,7 +1558,7 @@ func _1674210659_add_contact_request_local_clockUpSql() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "1674210659_add_contact_request_local_clock.up.sql", size: 691, mode: os.FileMode(0644), modTime: time.Unix(1675272378, 0)}
info := bindataFileInfo{name: "1674210659_add_contact_request_local_clock.up.sql", size: 691, mode: os.FileMode(0644), modTime: time.Unix(1675361522, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x92, 0x72, 0x39, 0xfe, 0x72, 0x98, 0xfc, 0x91, 0x20, 0x10, 0xe8, 0xf5, 0xac, 0x79, 0xa8, 0x1c, 0xca, 0x7b, 0x35, 0xa, 0xc1, 0x56, 0x49, 0x9a, 0xfc, 0xbd, 0x64, 0x9d, 0xdf, 0xd2, 0x60, 0x70}}
return a, nil
}
@ -1598,7 +1598,7 @@ func _1675272329_fix_protocol_migrationUpSql() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "1675272329_fix_protocol_migration.up.sql", size: 183, mode: os.FileMode(0644), modTime: time.Unix(1675272611, 0)}
info := bindataFileInfo{name: "1675272329_fix_protocol_migration.up.sql", size: 183, mode: os.FileMode(0644), modTime: time.Unix(1675361522, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xb6, 0xe0, 0x11, 0x4c, 0x66, 0x55, 0x72, 0xd3, 0xe6, 0x98, 0xa4, 0xe7, 0x44, 0xf9, 0x3b, 0x3a, 0x3f, 0xd9, 0x91, 0x1e, 0x4f, 0xfc, 0x56, 0x63, 0xe5, 0xa4, 0x83, 0xfc, 0x7c, 0xcf, 0x18, 0x99}}
return a, nil
}

View File

@ -867,9 +867,7 @@ type ChatMessage struct {
Grant []byte `protobuf:"bytes,13,opt,name=grant,proto3" json:"grant,omitempty"`
// Message author's display name, introduced in version 1
DisplayName string `protobuf:"bytes,14,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"`
SentContactRequestSignature *ContactRequestSignature `protobuf:"bytes,15,opt,name=sent_contact_request_signature,json=sentContactRequestSignature,proto3" json:"sent_contact_request_signature,omitempty"`
ReceivedContactRequestSignature *ContactRequestSignature `protobuf:"bytes,16,opt,name=received_contact_request_signature,json=receivedContactRequestSignature,proto3" json:"received_contact_request_signature,omitempty"`
ContactMessage bool `protobuf:"varint,17,opt,name=contact_message,json=contactMessage,proto3" json:"contact_message,omitempty"`
ContactRequestPropagatedState *ContactRequestPropagatedState `protobuf:"bytes,15,opt,name=contact_request_propagated_state,json=contactRequestPropagatedState,proto3" json:"contact_request_propagated_state,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -1046,27 +1044,13 @@ func (m *ChatMessage) GetDisplayName() string {
return ""
}
func (m *ChatMessage) GetSentContactRequestSignature() *ContactRequestSignature {
func (m *ChatMessage) GetContactRequestPropagatedState() *ContactRequestPropagatedState {
if m != nil {
return m.SentContactRequestSignature
return m.ContactRequestPropagatedState
}
return nil
}
func (m *ChatMessage) GetReceivedContactRequestSignature() *ContactRequestSignature {
if m != nil {
return m.ReceivedContactRequestSignature
}
return nil
}
func (m *ChatMessage) GetContactMessage() bool {
if m != nil {
return m.ContactMessage
}
return false
}
// XXX_OneofWrappers is for the internal use of the proto package.
func (*ChatMessage) XXX_OneofWrappers() []interface{} {
return []interface{}{
@ -1078,53 +1062,6 @@ func (*ChatMessage) XXX_OneofWrappers() []interface{} {
}
}
type ContactRequestSignature struct {
Signature []byte `protobuf:"bytes,1,opt,name=signature,proto3" json:"signature,omitempty"`
Timestamp uint64 `protobuf:"varint,2,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ContactRequestSignature) Reset() { *m = ContactRequestSignature{} }
func (m *ContactRequestSignature) String() string { return proto.CompactTextString(m) }
func (*ContactRequestSignature) ProtoMessage() {}
func (*ContactRequestSignature) Descriptor() ([]byte, []int) {
return fileDescriptor_263952f55fd35689, []int{11}
}
func (m *ContactRequestSignature) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ContactRequestSignature.Unmarshal(m, b)
}
func (m *ContactRequestSignature) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ContactRequestSignature.Marshal(b, m, deterministic)
}
func (m *ContactRequestSignature) XXX_Merge(src proto.Message) {
xxx_messageInfo_ContactRequestSignature.Merge(m, src)
}
func (m *ContactRequestSignature) XXX_Size() int {
return xxx_messageInfo_ContactRequestSignature.Size(m)
}
func (m *ContactRequestSignature) XXX_DiscardUnknown() {
xxx_messageInfo_ContactRequestSignature.DiscardUnknown(m)
}
var xxx_messageInfo_ContactRequestSignature proto.InternalMessageInfo
func (m *ContactRequestSignature) GetSignature() []byte {
if m != nil {
return m.Signature
}
return nil
}
func (m *ContactRequestSignature) GetTimestamp() uint64 {
if m != nil {
return m.Timestamp
}
return 0
}
func init() {
proto.RegisterEnum("protobuf.AudioMessage_AudioType", AudioMessage_AudioType_name, AudioMessage_AudioType_value)
proto.RegisterEnum("protobuf.ChatMessage_ContentType", ChatMessage_ContentType_name, ChatMessage_ContentType_value)
@ -1139,7 +1076,6 @@ func init() {
proto.RegisterType((*DiscordMessageReference)(nil), "protobuf.DiscordMessageReference")
proto.RegisterType((*DiscordMessageAttachment)(nil), "protobuf.DiscordMessageAttachment")
proto.RegisterType((*ChatMessage)(nil), "protobuf.ChatMessage")
proto.RegisterType((*ContactRequestSignature)(nil), "protobuf.ContactRequestSignature")
}
func init() {
@ -1147,87 +1083,84 @@ func init() {
}
var fileDescriptor_263952f55fd35689 = []byte{
// 1302 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x56, 0xcd, 0x92, 0xdb, 0xc4,
0x13, 0x5f, 0x7f, 0x5b, 0x2d, 0xdb, 0xab, 0xff, 0x64, 0x93, 0x55, 0xf2, 0xcf, 0x87, 0xa3, 0x4a,
0x55, 0x7c, 0x32, 0x55, 0x21, 0x50, 0xa9, 0xe2, 0x40, 0x69, 0x6d, 0x65, 0x23, 0x82, 0xed, 0x65,
0x2c, 0x07, 0x96, 0x8b, 0x4a, 0x2b, 0xcd, 0xae, 0x55, 0x6b, 0x4b, 0x46, 0x1a, 0x07, 0xcc, 0x9d,
0x23, 0x2f, 0xc0, 0x89, 0xa7, 0xe0, 0x29, 0xb8, 0xf2, 0x0a, 0x3c, 0x01, 0x0f, 0x40, 0xcd, 0x48,
0x23, 0x4b, 0x26, 0xde, 0xa4, 0x72, 0xd2, 0x74, 0xab, 0xbb, 0xe7, 0xd7, 0xbf, 0xee, 0xe9, 0x19,
0x40, 0xee, 0xdc, 0xa1, 0xf6, 0x92, 0xc4, 0xb1, 0x73, 0x45, 0xfa, 0xab, 0x28, 0xa4, 0x21, 0x6a,
0xf2, 0xcf, 0xc5, 0xfa, 0xf2, 0x9e, 0x4c, 0x82, 0xf5, 0x32, 0x4e, 0xd4, 0xda, 0x0b, 0xe8, 0x4c,
0xa9, 0xef, 0x5e, 0x93, 0x68, 0x94, 0x98, 0x23, 0x04, 0xd5, 0xb9, 0x13, 0xcf, 0xd5, 0x52, 0xb7,
0xd4, 0x93, 0x30, 0x5f, 0x33, 0xdd, 0xca, 0x71, 0xaf, 0xd5, 0x72, 0xb7, 0xd4, 0xab, 0x61, 0xbe,
0xd6, 0x7e, 0x2b, 0x41, 0xcb, 0x5c, 0x3a, 0x57, 0x44, 0x38, 0xaa, 0xd0, 0x58, 0x39, 0x9b, 0x45,
0xe8, 0x78, 0xdc, 0xb7, 0x85, 0x85, 0x88, 0x9e, 0x42, 0x95, 0x6e, 0x56, 0x84, 0xbb, 0x77, 0x9e,
0xdd, 0xea, 0x0b, 0x28, 0x7d, 0xee, 0x6f, 0x6d, 0x56, 0x04, 0x73, 0x03, 0x74, 0x17, 0x9a, 0xce,
0xe2, 0x62, 0xbd, 0xb4, 0x7d, 0x4f, 0xad, 0xf0, 0xfd, 0x1b, 0x5c, 0x36, 0x3d, 0x74, 0x04, 0xb5,
0x1f, 0x7d, 0x8f, 0xce, 0xd5, 0x6a, 0xb7, 0xd4, 0x6b, 0xe3, 0x44, 0x40, 0x77, 0xa0, 0x3e, 0x27,
0xfe, 0xd5, 0x9c, 0xaa, 0x35, 0xae, 0x4e, 0x25, 0xed, 0x8f, 0x12, 0xb4, 0xf4, 0xb5, 0xe7, 0x87,
0xef, 0x07, 0xf7, 0xbc, 0x00, 0xae, 0xbb, 0x05, 0x97, 0xf7, 0x4f, 0x84, 0x1c, 0xd2, 0x47, 0x20,
0x7b, 0xeb, 0xc8, 0xa1, 0x7e, 0x18, 0xd8, 0xcb, 0x98, 0x83, 0xad, 0x62, 0x10, 0xaa, 0x51, 0xac,
0x7d, 0x06, 0x52, 0xe6, 0x83, 0xee, 0x00, 0x9a, 0x8d, 0x5f, 0x8f, 0x27, 0xdf, 0x8e, 0x6d, 0x7d,
0x36, 0x34, 0x27, 0xb6, 0x75, 0x7e, 0x66, 0x28, 0x07, 0xa8, 0x01, 0x15, 0x5d, 0x1f, 0x28, 0x25,
0xbe, 0x18, 0x61, 0xa5, 0xac, 0xfd, 0x52, 0x06, 0xd9, 0xf0, 0x7c, 0x2a, 0x70, 0x1f, 0x41, 0xcd,
0x5d, 0x84, 0xee, 0x35, 0x47, 0x5d, 0xc5, 0x89, 0xc0, 0xea, 0x41, 0xc9, 0x4f, 0x94, 0x63, 0x96,
0x30, 0x5f, 0xa3, 0x63, 0x68, 0xf0, 0xb2, 0x67, 0xd4, 0xd5, 0x99, 0x68, 0x7a, 0xe8, 0x01, 0x40,
0xda, 0x0a, 0xec, 0x5f, 0x95, 0xff, 0x93, 0x52, 0x4d, 0x42, 0xec, 0x55, 0xe4, 0x04, 0x09, 0x83,
0x2d, 0x9c, 0x08, 0xe8, 0x05, 0xb4, 0x84, 0x13, 0x67, 0xa7, 0xce, 0xd9, 0xb9, 0xbd, 0x65, 0x27,
0x05, 0xc8, 0x29, 0x91, 0x97, 0x5b, 0x01, 0x0d, 0xa1, 0xe5, 0x86, 0x01, 0x25, 0x01, 0x4d, 0x3c,
0x1b, 0xdc, 0xf3, 0xf1, 0xd6, 0x73, 0x30, 0x77, 0x44, 0x7a, 0xfd, 0x41, 0x62, 0x99, 0x44, 0x71,
0xb7, 0x82, 0xf6, 0x67, 0x09, 0xda, 0x43, 0xb2, 0x20, 0x94, 0xdc, 0xcc, 0x44, 0x2e, 0xeb, 0xf2,
0x0d, 0x59, 0x57, 0xf6, 0x66, 0x5d, 0xbd, 0x29, 0xeb, 0xda, 0x07, 0x67, 0xfd, 0x00, 0xc0, 0xe3,
0x70, 0x3d, 0xfb, 0x62, 0xc3, 0xd9, 0x92, 0xb0, 0x94, 0x6a, 0x4e, 0x36, 0x9a, 0x09, 0x28, 0xc9,
0xe6, 0x65, 0x18, 0x8d, 0xde, 0x93, 0x52, 0x11, 0x79, 0x79, 0x07, 0xb9, 0xf6, 0x57, 0x19, 0x3a,
0x43, 0x3f, 0x76, 0xc3, 0xc8, 0x13, 0x71, 0x3a, 0x50, 0xf6, 0xbd, 0xf4, 0xc0, 0x96, 0x7d, 0x8f,
0xb7, 0x87, 0x68, 0x69, 0x29, 0x6d, 0xd8, 0xfb, 0x20, 0x51, 0x7f, 0x49, 0x62, 0xea, 0x2c, 0x57,
0x82, 0x8e, 0x4c, 0x81, 0x7a, 0x70, 0x98, 0x09, 0xac, 0xfd, 0x88, 0x68, 0x94, 0x5d, 0x35, 0x3b,
0x48, 0x69, 0x9d, 0x38, 0x3b, 0x12, 0x16, 0x22, 0xfa, 0x1c, 0xea, 0xce, 0x9a, 0xce, 0xc3, 0x88,
0xa7, 0x2f, 0x3f, 0x7b, 0xb8, 0xa5, 0xad, 0x88, 0x57, 0xe7, 0x56, 0x38, 0xb5, 0x46, 0x5f, 0x82,
0x14, 0x91, 0x4b, 0x12, 0x91, 0xc0, 0x4d, 0xba, 0x45, 0xce, 0x77, 0x4b, 0xd1, 0x15, 0x0b, 0x43,
0xbc, 0xf5, 0x41, 0x43, 0x90, 0x1d, 0x4a, 0x1d, 0x77, 0xbe, 0x24, 0x01, 0x8d, 0xd5, 0x66, 0xb7,
0xd2, 0x93, 0x9f, 0x69, 0x7b, 0x77, 0xcf, 0x4c, 0x71, 0xde, 0x4d, 0xfb, 0xbb, 0x04, 0x47, 0xef,
0xc2, 0xf9, 0x2e, 0x76, 0x03, 0x67, 0x99, 0xb1, 0xcb, 0xd6, 0xe8, 0x09, 0xb4, 0x3d, 0x3f, 0x76,
0x23, 0x7f, 0xe9, 0x07, 0x0e, 0x0d, 0xa3, 0x94, 0xe1, 0xa2, 0x12, 0xdd, 0x83, 0x66, 0xe0, 0xbb,
0xd7, 0xdc, 0x3b, 0xa1, 0x37, 0x93, 0x59, 0x7d, 0x9c, 0xb7, 0x0e, 0x75, 0xa2, 0x59, 0xb4, 0x48,
0x99, 0xdd, 0x2a, 0x50, 0x1f, 0x50, 0x22, 0xf0, 0x89, 0x79, 0x96, 0x4e, 0xb2, 0x3a, 0xef, 0xdd,
0x77, 0xfc, 0x61, 0x3b, 0x2d, 0x42, 0xd7, 0x59, 0xb0, 0x60, 0x8d, 0x64, 0x27, 0x21, 0x6b, 0x21,
0x1c, 0xef, 0x21, 0x95, 0x81, 0xc8, 0x1a, 0x2d, 0xcd, 0x38, 0x77, 0x66, 0xee, 0x83, 0xe4, 0xce,
0x9d, 0x20, 0x20, 0x0b, 0x33, 0xeb, 0xcb, 0x4c, 0xc1, 0x1a, 0xe3, 0x6a, 0xed, 0x2f, 0x3c, 0x33,
0x1b, 0xdd, 0xa9, 0xa8, 0xfd, 0x53, 0x02, 0x75, 0x5f, 0x0d, 0xfe, 0xc3, 0x6e, 0x01, 0xc2, 0x6e,
0xf3, 0x23, 0x05, 0x2a, 0xeb, 0x68, 0x91, 0x6e, 0xc0, 0x96, 0x2c, 0xd3, 0x4b, 0x7f, 0x41, 0xc6,
0x39, 0x4e, 0x85, 0xcc, 0xaa, 0xc2, 0xd6, 0x53, 0xff, 0x67, 0x72, 0xb2, 0xa1, 0x24, 0xe6, 0xbc,
0x56, 0x71, 0x51, 0x89, 0xba, 0x90, 0x9f, 0x3c, 0xe9, 0xd9, 0xcd, 0xab, 0xf2, 0x97, 0x47, 0xa3,
0x78, 0x79, 0xe4, 0x79, 0x6e, 0xee, 0xf0, 0xfc, 0xab, 0x04, 0x72, 0x6e, 0xd6, 0xed, 0x39, 0xed,
0x85, 0x73, 0x59, 0xe6, 0x7f, 0x72, 0xe7, 0x52, 0x0c, 0xfa, 0x4a, 0x6e, 0xd0, 0x3f, 0x02, 0x39,
0x22, 0xf1, 0x2a, 0x0c, 0x62, 0x62, 0xd3, 0x30, 0x4d, 0x1a, 0x84, 0xca, 0x0a, 0xd9, 0x2d, 0x4a,
0x82, 0xd8, 0xe6, 0x6d, 0x96, 0x9e, 0x51, 0x12, 0xc4, 0x9c, 0x91, 0xdc, 0xb8, 0xac, 0x17, 0xc6,
0xe5, 0xee, 0xe4, 0x6b, 0x7c, 0xf4, 0xbc, 0x6f, 0x7e, 0xcc, 0xbc, 0x47, 0xcf, 0xa1, 0x11, 0x27,
0xef, 0x10, 0x55, 0xe2, 0x23, 0x40, 0xdd, 0x06, 0x28, 0x3e, 0x50, 0x5e, 0x1d, 0x60, 0x61, 0x8a,
0xfa, 0x50, 0xf3, 0x59, 0xdb, 0xab, 0xc0, 0x7d, 0xee, 0xec, 0xbc, 0x2c, 0xb6, 0x1e, 0x89, 0x19,
0xb3, 0x77, 0xd8, 0xa5, 0xac, 0xca, 0xbb, 0xf6, 0xf9, 0xcb, 0x9e, 0xd9, 0x73, 0x33, 0xf4, 0x10,
0x24, 0x37, 0x5c, 0x2e, 0xd7, 0x81, 0x4f, 0x37, 0x6a, 0x8b, 0x95, 0xfe, 0xd5, 0x01, 0xde, 0xaa,
0xd0, 0x00, 0x0e, 0xbd, 0xa4, 0xb1, 0xc5, 0x6b, 0x4b, 0x75, 0x77, 0xd1, 0x17, 0x3b, 0xff, 0xd5,
0x01, 0xee, 0x78, 0xc5, 0xe9, 0x9d, 0x5d, 0x45, 0xed, 0xfc, 0x55, 0xf4, 0x18, 0x5a, 0x9e, 0x1f,
0xaf, 0x16, 0xce, 0x26, 0x29, 0x64, 0x27, 0x69, 0xcb, 0x54, 0xc7, 0x8b, 0x79, 0x09, 0x0f, 0x63,
0x46, 0x3b, 0xe3, 0xd1, 0x71, 0xa9, 0x1d, 0x91, 0x1f, 0xd6, 0x24, 0xa6, 0x76, 0xec, 0x5f, 0x05,
0x0e, 0x5d, 0x47, 0x44, 0x3d, 0xdc, 0x9d, 0xa6, 0x83, 0xc4, 0x14, 0x27, 0x96, 0x53, 0x61, 0x88,
0xff, 0xcf, 0x02, 0xed, 0xf9, 0x89, 0x02, 0xd0, 0x22, 0xe2, 0x12, 0xff, 0x2d, 0xf1, 0x6e, 0xd8,
0x4b, 0xf9, 0xd0, 0xbd, 0x1e, 0x89, 0x60, 0xfb, 0xf6, 0x7b, 0x0a, 0x87, 0x62, 0x1b, 0xc1, 0xea,
0xff, 0xba, 0xa5, 0x5e, 0x13, 0x77, 0x52, 0x75, 0xca, 0x9c, 0xf6, 0x7b, 0x19, 0xe4, 0x41, 0xe1,
0x9c, 0x1e, 0x89, 0x67, 0xd6, 0x60, 0x32, 0xb6, 0x8c, 0xb1, 0x25, 0x1e, 0x5a, 0x1d, 0x00, 0xcb,
0xf8, 0xce, 0xb2, 0xcf, 0xbe, 0xd6, 0xcd, 0xb1, 0x52, 0x42, 0x32, 0x34, 0xa6, 0x96, 0x39, 0x78,
0x6d, 0x60, 0xa5, 0x8c, 0x00, 0xea, 0x53, 0x4b, 0xb7, 0x66, 0x53, 0xa5, 0x82, 0x24, 0xa8, 0x19,
0xa3, 0xc9, 0x57, 0xa6, 0x52, 0x45, 0xc7, 0x70, 0xcb, 0xc2, 0xfa, 0x78, 0xaa, 0x0f, 0x2c, 0x73,
0xc2, 0x22, 0x8e, 0x46, 0xfa, 0x78, 0xa8, 0xd4, 0x50, 0x0f, 0x9e, 0x4c, 0xcf, 0xa7, 0x96, 0x31,
0xb2, 0x47, 0xc6, 0x74, 0xaa, 0x9f, 0x1a, 0xd9, 0x6e, 0x67, 0xd8, 0x7c, 0xa3, 0x5b, 0x86, 0x7d,
0x8a, 0x27, 0xb3, 0x33, 0xa5, 0xce, 0xa2, 0x99, 0x23, 0xfd, 0xd4, 0x50, 0x1a, 0x6c, 0xc9, 0x9f,
0x7e, 0x4a, 0x13, 0xb5, 0x41, 0x62, 0xc1, 0x66, 0x63, 0xd3, 0x3a, 0x57, 0x24, 0xf6, 0x38, 0xdc,
0x09, 0x77, 0xaa, 0x9f, 0x29, 0x80, 0x6e, 0xc1, 0x21, 0x8b, 0xab, 0x0f, 0x2c, 0x1b, 0x1b, 0xdf,
0xcc, 0x8c, 0xa9, 0xa5, 0xc8, 0x4c, 0x39, 0x34, 0xa7, 0x83, 0x09, 0x1e, 0x0a, 0x6b, 0xa5, 0x85,
0xee, 0xc2, 0x6d, 0x73, 0x68, 0x8c, 0x2d, 0xd3, 0x3a, 0xb7, 0xdf, 0x18, 0xd8, 0x7c, 0x69, 0x0e,
0x74, 0x86, 0x59, 0x69, 0x9f, 0x48, 0xd9, 0xe8, 0xd2, 0x66, 0x70, 0xbc, 0x8f, 0xf1, 0xfb, 0x20,
0x6d, 0x0b, 0x99, 0xbc, 0x8f, 0xb7, 0x8a, 0x9b, 0x47, 0xd4, 0x49, 0xfb, 0x7b, 0xb9, 0xff, 0xc9,
0x17, 0xa2, 0xea, 0x17, 0x75, 0xbe, 0xfa, 0xf4, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x5b, 0x61,
0xf8, 0x08, 0x84, 0x0c, 0x00, 0x00,
// 1257 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x56, 0xcb, 0x8e, 0xdb, 0x36,
0x17, 0x1e, 0x7b, 0x7c, 0xd3, 0x91, 0xed, 0x11, 0x98, 0x49, 0xa2, 0x04, 0xb9, 0x38, 0x42, 0x80,
0xcc, 0xca, 0x3f, 0x90, 0x3f, 0x2d, 0x02, 0x74, 0x51, 0x68, 0x6c, 0x65, 0xa2, 0xa6, 0xbe, 0x94,
0x92, 0xd3, 0x4e, 0x37, 0x02, 0x47, 0x62, 0xc6, 0xc2, 0x58, 0x92, 0x2b, 0xd1, 0x6d, 0xdd, 0x7d,
0x5f, 0xa2, 0xab, 0x3e, 0x45, 0x9f, 0xa2, 0xdb, 0xbe, 0x42, 0x9f, 0xa0, 0xeb, 0xa2, 0x20, 0x75,
0xb1, 0xe4, 0x66, 0x26, 0x45, 0x56, 0xe2, 0x39, 0x3a, 0x87, 0xfc, 0xce, 0xc7, 0x8f, 0x87, 0x04,
0xe4, 0x2e, 0x09, 0x73, 0x02, 0x9a, 0x24, 0xe4, 0x92, 0x0e, 0xd7, 0x71, 0xc4, 0x22, 0xd4, 0x11,
0x9f, 0x8b, 0xcd, 0xbb, 0xfb, 0x32, 0x0d, 0x37, 0x41, 0x92, 0xba, 0xef, 0xf7, 0xdc, 0x28, 0x64,
0xc4, 0x65, 0xa9, 0xa9, 0xbd, 0x84, 0xbe, 0xc5, 0x7c, 0xf7, 0x8a, 0xc6, 0x93, 0x34, 0x1b, 0x21,
0x68, 0x2c, 0x49, 0xb2, 0x54, 0x6b, 0x83, 0xda, 0x89, 0x84, 0xc5, 0x98, 0xfb, 0xd6, 0xc4, 0xbd,
0x52, 0xeb, 0x83, 0xda, 0x49, 0x13, 0x8b, 0xb1, 0xf6, 0x4b, 0x0d, 0xba, 0x66, 0x40, 0x2e, 0x69,
0x9e, 0xa8, 0x42, 0x7b, 0x4d, 0xb6, 0xab, 0x88, 0x78, 0x22, 0xb7, 0x8b, 0x73, 0x13, 0x3d, 0x83,
0x06, 0xdb, 0xae, 0xa9, 0x48, 0xef, 0x3f, 0xbf, 0x35, 0xcc, 0x91, 0x0d, 0x45, 0xbe, 0xbd, 0x5d,
0x53, 0x2c, 0x02, 0xd0, 0x3d, 0xe8, 0x90, 0xd5, 0xc5, 0x26, 0x70, 0x7c, 0x4f, 0x3d, 0x14, 0xeb,
0xb7, 0x85, 0x6d, 0x7a, 0xe8, 0x18, 0x9a, 0x3f, 0xf8, 0x1e, 0x5b, 0xaa, 0x8d, 0x41, 0xed, 0xa4,
0x87, 0x53, 0x03, 0xdd, 0x81, 0xd6, 0x92, 0xfa, 0x97, 0x4b, 0xa6, 0x36, 0x85, 0x3b, 0xb3, 0xb4,
0xdf, 0x6a, 0xd0, 0xd5, 0x37, 0x9e, 0x1f, 0x7d, 0x18, 0xdc, 0x8b, 0x0a, 0xb8, 0xc1, 0x0e, 0x5c,
0x39, 0x3f, 0x35, 0x4a, 0x48, 0x1f, 0x83, 0xec, 0x6d, 0x62, 0xc2, 0xfc, 0x28, 0x74, 0x82, 0x44,
0x80, 0x6d, 0x60, 0xc8, 0x5d, 0x93, 0x44, 0xfb, 0x04, 0xa4, 0x22, 0x07, 0xdd, 0x01, 0xb4, 0x98,
0xbe, 0x99, 0xce, 0xbe, 0x9e, 0x3a, 0xfa, 0x62, 0x6c, 0xce, 0x1c, 0xfb, 0x7c, 0x6e, 0x28, 0x07,
0xa8, 0x0d, 0x87, 0xba, 0x3e, 0x52, 0x6a, 0x62, 0x30, 0xc1, 0x4a, 0x5d, 0xfb, 0xb9, 0x0e, 0xb2,
0xe1, 0xf9, 0x2c, 0xc7, 0x7d, 0x0c, 0x4d, 0x77, 0x15, 0xb9, 0x57, 0x02, 0x75, 0x03, 0xa7, 0x06,
0xdf, 0x0f, 0x46, 0x7f, 0x64, 0x02, 0xb3, 0x84, 0xc5, 0x18, 0xdd, 0x85, 0xb6, 0x50, 0x41, 0x41,
0x5d, 0x8b, 0x9b, 0xa6, 0x87, 0x1e, 0x02, 0x64, 0xca, 0xe0, 0xff, 0x1a, 0xe2, 0x9f, 0x94, 0x79,
0x52, 0x62, 0x2f, 0x63, 0x12, 0xa6, 0x0c, 0x76, 0x71, 0x6a, 0xa0, 0x97, 0xd0, 0xcd, 0x93, 0x04,
0x3b, 0x2d, 0xc1, 0xce, 0xed, 0x1d, 0x3b, 0x19, 0x40, 0x41, 0x89, 0x1c, 0xec, 0x0c, 0x34, 0x86,
0x2e, 0x97, 0x18, 0x0d, 0x59, 0x9a, 0xd9, 0x16, 0x99, 0x4f, 0x76, 0x99, 0xa3, 0x25, 0xc9, 0xcb,
0x1b, 0x8e, 0xd2, 0xc8, 0x74, 0x16, 0x77, 0x67, 0x68, 0xbf, 0xd7, 0xa0, 0x37, 0xa6, 0x2b, 0xca,
0xe8, 0xcd, 0x4c, 0x94, 0xaa, 0xae, 0xdf, 0x50, 0xf5, 0xe1, 0xb5, 0x55, 0x37, 0x6e, 0xaa, 0xba,
0xf9, 0x9f, 0xab, 0x7e, 0x08, 0xe0, 0x09, 0xb8, 0x9e, 0x73, 0xb1, 0x15, 0x6c, 0x49, 0x58, 0xca,
0x3c, 0xa7, 0x5b, 0xcd, 0x04, 0x94, 0x56, 0xf3, 0x2a, 0x8a, 0x27, 0x1f, 0x28, 0xa9, 0x8a, 0xbc,
0xbe, 0x87, 0x5c, 0xfb, 0xa3, 0x0e, 0xfd, 0xb1, 0x9f, 0xb8, 0x51, 0xec, 0xe5, 0xf3, 0xf4, 0xa1,
0xee, 0x7b, 0xd9, 0x81, 0xad, 0xfb, 0x9e, 0x90, 0x47, 0x2e, 0x69, 0x29, 0x13, 0xec, 0x03, 0x90,
0x98, 0x1f, 0xd0, 0x84, 0x91, 0x60, 0x9d, 0xd3, 0x51, 0x38, 0xd0, 0x09, 0x1c, 0x15, 0x06, 0x97,
0x1f, 0xcd, 0x85, 0xb2, 0xef, 0xe6, 0x07, 0x29, 0xdb, 0x27, 0xc1, 0x8e, 0x84, 0x73, 0x13, 0x7d,
0x0a, 0x2d, 0xb2, 0x61, 0xcb, 0x28, 0x16, 0xe5, 0xcb, 0xcf, 0x1f, 0xed, 0x68, 0xab, 0xe2, 0xd5,
0x45, 0x14, 0xce, 0xa2, 0xd1, 0xe7, 0x20, 0xc5, 0xf4, 0x1d, 0x8d, 0x69, 0xe8, 0xa6, 0x6a, 0x91,
0xcb, 0x6a, 0xa9, 0xa6, 0xe2, 0x3c, 0x10, 0xef, 0x72, 0xd0, 0x18, 0x64, 0xc2, 0x18, 0x71, 0x97,
0x01, 0x0d, 0x59, 0xa2, 0x76, 0x06, 0x87, 0x27, 0xf2, 0x73, 0xed, 0xda, 0xd5, 0x8b, 0x50, 0x5c,
0x4e, 0xd3, 0xfe, 0xac, 0xc1, 0xf1, 0xfb, 0x70, 0xbe, 0x8f, 0xdd, 0x90, 0x04, 0x05, 0xbb, 0x7c,
0x8c, 0x9e, 0x42, 0xcf, 0xf3, 0x13, 0x37, 0xf6, 0x03, 0x3f, 0x24, 0x2c, 0x8a, 0x33, 0x86, 0xab,
0x4e, 0x74, 0x1f, 0x3a, 0xa1, 0xef, 0x5e, 0x89, 0xec, 0x94, 0xde, 0xc2, 0xe6, 0xfb, 0x43, 0xbe,
0x27, 0x8c, 0xc4, 0x8b, 0x78, 0x95, 0x31, 0xbb, 0x73, 0xa0, 0x21, 0xa0, 0xd4, 0x10, 0x1d, 0x73,
0x9e, 0x75, 0xb2, 0x96, 0xd0, 0xee, 0x7b, 0xfe, 0xf0, 0x95, 0x56, 0x91, 0x4b, 0x56, 0x7c, 0xb2,
0x76, 0xba, 0x52, 0x6e, 0x6b, 0x11, 0xdc, 0xbd, 0x86, 0x54, 0x0e, 0xa2, 0x10, 0x5a, 0x56, 0x71,
0xe9, 0xcc, 0x3c, 0x00, 0xc9, 0x5d, 0x92, 0x30, 0xa4, 0x2b, 0xb3, 0xd0, 0x65, 0xe1, 0xe0, 0xc2,
0xb8, 0xdc, 0xf8, 0x2b, 0xcf, 0x2c, 0x5a, 0x77, 0x66, 0x6a, 0x7f, 0xd5, 0x40, 0xbd, 0x6e, 0x0f,
0xfe, 0xc5, 0x6e, 0x05, 0xc2, 0xbe, 0xf8, 0x91, 0x02, 0x87, 0x9b, 0x78, 0x95, 0x2d, 0xc0, 0x87,
0xbc, 0xd2, 0x77, 0xfe, 0x8a, 0x4e, 0x4b, 0x9c, 0xe6, 0x36, 0xdf, 0x15, 0x3e, 0xb6, 0xfc, 0x9f,
0xe8, 0xe9, 0x96, 0xd1, 0x44, 0xf0, 0xda, 0xc0, 0x55, 0x27, 0x1a, 0x40, 0xb9, 0xf3, 0x64, 0x67,
0xb7, 0xec, 0x2a, 0x5f, 0x1e, 0xed, 0xea, 0xe5, 0x51, 0xe6, 0xb9, 0xb3, 0xc7, 0xf3, 0xdf, 0x6d,
0x90, 0x4b, 0xbd, 0xee, 0x9a, 0xd3, 0x5e, 0x39, 0x97, 0x75, 0xf1, 0xa7, 0x74, 0x2e, 0xf3, 0x46,
0x7f, 0x58, 0x6a, 0xf4, 0x8f, 0x41, 0x8e, 0x69, 0xb2, 0x8e, 0xc2, 0x84, 0x3a, 0x2c, 0xca, 0x8a,
0x86, 0xdc, 0x65, 0x47, 0xfc, 0x16, 0xa5, 0x61, 0xe2, 0x08, 0x99, 0x65, 0x67, 0x94, 0x86, 0x89,
0x60, 0xa4, 0xd4, 0x2e, 0x5b, 0x95, 0x76, 0xb9, 0xdf, 0xf9, 0xda, 0x1f, 0xdd, 0xef, 0x3b, 0x1f,
0xd3, 0xef, 0xd1, 0x0b, 0x68, 0x27, 0xe9, 0x3b, 0x44, 0x95, 0x44, 0x0b, 0x50, 0x77, 0x13, 0x54,
0x1f, 0x28, 0xaf, 0x0f, 0x70, 0x1e, 0x8a, 0x86, 0xd0, 0xf4, 0xb9, 0xec, 0x55, 0x10, 0x39, 0x77,
0xf6, 0x5e, 0x16, 0xbb, 0x8c, 0x34, 0x8c, 0xc7, 0x13, 0x7e, 0x29, 0xab, 0xf2, 0x7e, 0x7c, 0xf9,
0xb2, 0xe7, 0xf1, 0x22, 0x0c, 0x3d, 0x02, 0xc9, 0x8d, 0x82, 0x60, 0x13, 0xfa, 0x6c, 0xab, 0x76,
0xf9, 0xd6, 0xbf, 0x3e, 0xc0, 0x3b, 0x17, 0x1a, 0xc1, 0x91, 0x97, 0x0a, 0x3b, 0x7f, 0x7c, 0xa9,
0xee, 0x3e, 0xfa, 0xaa, 0xf2, 0x5f, 0x1f, 0xe0, 0xbe, 0x57, 0xed, 0xde, 0xc5, 0x55, 0xd4, 0x2b,
0x5f, 0x45, 0x4f, 0xa0, 0xeb, 0xf9, 0xc9, 0x7a, 0x45, 0xb6, 0xe9, 0x46, 0xf6, 0x53, 0x59, 0x66,
0x3e, 0xb1, 0x99, 0x6b, 0x18, 0x64, 0x8f, 0x39, 0x27, 0xa6, 0xdf, 0x6d, 0x68, 0xc2, 0x9c, 0x75,
0x1c, 0xad, 0xc9, 0x25, 0xe1, 0xd7, 0x50, 0xc2, 0x08, 0xa3, 0xea, 0x91, 0x80, 0xf3, 0xac, 0xb4,
0x1b, 0x69, 0x06, 0x4e, 0x13, 0xe6, 0x45, 0xbc, 0xc5, 0xc3, 0xf1, 0x43, 0xf7, 0xa6, 0xdf, 0xda,
0xaf, 0x75, 0x90, 0x47, 0x95, 0x83, 0x71, 0x9c, 0xbf, 0x6b, 0x46, 0xb3, 0xa9, 0x6d, 0x4c, 0xed,
0xfc, 0x65, 0xd3, 0x07, 0xb0, 0x8d, 0x6f, 0x6c, 0x67, 0xfe, 0xa5, 0x6e, 0x4e, 0x95, 0x1a, 0x92,
0xa1, 0x6d, 0xd9, 0xe6, 0xe8, 0x8d, 0x81, 0x95, 0x3a, 0x02, 0x68, 0x59, 0xb6, 0x6e, 0x2f, 0x2c,
0xe5, 0x10, 0x49, 0xd0, 0x34, 0x26, 0xb3, 0x2f, 0x4c, 0xa5, 0x81, 0xee, 0xc2, 0x2d, 0x1b, 0xeb,
0x53, 0x4b, 0x1f, 0xd9, 0xe6, 0x8c, 0xcf, 0x38, 0x99, 0xe8, 0xd3, 0xb1, 0xd2, 0x44, 0x27, 0xf0,
0xd4, 0x3a, 0xb7, 0x6c, 0x63, 0xe2, 0x4c, 0x0c, 0xcb, 0xd2, 0xcf, 0x8c, 0x62, 0xb5, 0x39, 0x36,
0xdf, 0xea, 0xb6, 0xe1, 0x9c, 0xe1, 0xd9, 0x62, 0xae, 0xb4, 0xf8, 0x6c, 0xe6, 0x44, 0x3f, 0x33,
0x94, 0x36, 0x1f, 0x8a, 0xb7, 0x96, 0xd2, 0x41, 0x3d, 0x90, 0xf8, 0x64, 0x8b, 0xa9, 0x69, 0x9f,
0x2b, 0x12, 0x7f, 0x8d, 0xed, 0x4d, 0x77, 0xa6, 0xcf, 0x15, 0x40, 0xb7, 0xe0, 0x88, 0xcf, 0xab,
0x8f, 0x6c, 0x07, 0x1b, 0x5f, 0x2d, 0x0c, 0xcb, 0x56, 0x64, 0xee, 0x1c, 0x9b, 0xd6, 0x68, 0x86,
0xc7, 0x79, 0xb4, 0xd2, 0x45, 0xf7, 0xe0, 0xb6, 0x39, 0x36, 0xa6, 0xb6, 0x69, 0x9f, 0x3b, 0x6f,
0x0d, 0x6c, 0xbe, 0x32, 0x47, 0x3a, 0xc7, 0xac, 0xf4, 0x4e, 0xa5, 0xa2, 0x57, 0x9c, 0xf6, 0xbe,
0x95, 0x87, 0xff, 0xfb, 0x2c, 0x67, 0xfe, 0xa2, 0x25, 0x46, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff,
0xff, 0xbb, 0x9e, 0xc6, 0x61, 0xad, 0x0b, 0x00, 0x00,
}

View File

@ -4,6 +4,7 @@ option go_package = "./;protobuf";
package protobuf;
import "enums.proto";
import "contact.proto";
message StickerMessage {
string hash = 1;
@ -142,9 +143,7 @@ message ChatMessage {
// Message author's display name, introduced in version 1
string display_name = 14;
ContactRequestSignature sent_contact_request_signature = 15;
ContactRequestSignature received_contact_request_signature = 16;
bool contact_message = 17;
ContactRequestPropagatedState contact_request_propagated_state = 15;
enum ContentType {
UNKNOWN_CONTENT_TYPE = 0;
@ -165,8 +164,3 @@ message ChatMessage {
IDENTITY_VERIFICATION = 13;
}
}
message ContactRequestSignature {
bytes signature = 1;
uint64 timestamp = 2;
}

View File

@ -20,14 +20,76 @@ var _ = math.Inf
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
type ContactRequestPropagatedState struct {
LocalClock uint64 `protobuf:"varint,1,opt,name=local_clock,json=localClock,proto3" json:"local_clock,omitempty"`
LocalState uint64 `protobuf:"varint,2,opt,name=local_state,json=localState,proto3" json:"local_state,omitempty"`
RemoteClock uint64 `protobuf:"varint,3,opt,name=remote_clock,json=remoteClock,proto3" json:"remote_clock,omitempty"`
RemoteState uint64 `protobuf:"varint,4,opt,name=remote_state,json=remoteState,proto3" json:"remote_state,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ContactRequestPropagatedState) Reset() { *m = ContactRequestPropagatedState{} }
func (m *ContactRequestPropagatedState) String() string { return proto.CompactTextString(m) }
func (*ContactRequestPropagatedState) ProtoMessage() {}
func (*ContactRequestPropagatedState) Descriptor() ([]byte, []int) {
return fileDescriptor_a5036fff2565fb15, []int{0}
}
func (m *ContactRequestPropagatedState) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ContactRequestPropagatedState.Unmarshal(m, b)
}
func (m *ContactRequestPropagatedState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ContactRequestPropagatedState.Marshal(b, m, deterministic)
}
func (m *ContactRequestPropagatedState) XXX_Merge(src proto.Message) {
xxx_messageInfo_ContactRequestPropagatedState.Merge(m, src)
}
func (m *ContactRequestPropagatedState) XXX_Size() int {
return xxx_messageInfo_ContactRequestPropagatedState.Size(m)
}
func (m *ContactRequestPropagatedState) XXX_DiscardUnknown() {
xxx_messageInfo_ContactRequestPropagatedState.DiscardUnknown(m)
}
var xxx_messageInfo_ContactRequestPropagatedState proto.InternalMessageInfo
func (m *ContactRequestPropagatedState) GetLocalClock() uint64 {
if m != nil {
return m.LocalClock
}
return 0
}
func (m *ContactRequestPropagatedState) GetLocalState() uint64 {
if m != nil {
return m.LocalState
}
return 0
}
func (m *ContactRequestPropagatedState) GetRemoteClock() uint64 {
if m != nil {
return m.RemoteClock
}
return 0
}
func (m *ContactRequestPropagatedState) GetRemoteState() uint64 {
if m != nil {
return m.RemoteState
}
return 0
}
type ContactUpdate struct {
Clock uint64 `protobuf:"varint,1,opt,name=clock,proto3" json:"clock,omitempty"`
EnsName string `protobuf:"bytes,2,opt,name=ens_name,json=ensName,proto3" json:"ens_name,omitempty"`
ProfileImage string `protobuf:"bytes,3,opt,name=profile_image,json=profileImage,proto3" json:"profile_image,omitempty"`
DisplayName string `protobuf:"bytes,4,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"`
ContactRequestClock uint64 `protobuf:"varint,5,opt,name=contact_request_clock,json=contactRequestClock,proto3" json:"contact_request_clock,omitempty"`
SentContactRequestSignature *ContactRequestSignature `protobuf:"bytes,14,opt,name=sent_contact_request_signature,json=sentContactRequestSignature,proto3" json:"sent_contact_request_signature,omitempty"`
ReceivedContactRequestSignature *ContactRequestSignature `protobuf:"bytes,15,opt,name=received_contact_request_signature,json=receivedContactRequestSignature,proto3" json:"received_contact_request_signature,omitempty"`
ContactRequestPropagatedState *ContactRequestPropagatedState `protobuf:"bytes,6,opt,name=contact_request_propagated_state,json=contactRequestPropagatedState,proto3" json:"contact_request_propagated_state,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -37,7 +99,7 @@ func (m *ContactUpdate) Reset() { *m = ContactUpdate{} }
func (m *ContactUpdate) String() string { return proto.CompactTextString(m) }
func (*ContactUpdate) ProtoMessage() {}
func (*ContactUpdate) Descriptor() ([]byte, []int) {
return fileDescriptor_a5036fff2565fb15, []int{0}
return fileDescriptor_a5036fff2565fb15, []int{1}
}
func (m *ContactUpdate) XXX_Unmarshal(b []byte) error {
@ -93,16 +155,9 @@ func (m *ContactUpdate) GetContactRequestClock() uint64 {
return 0
}
func (m *ContactUpdate) GetSentContactRequestSignature() *ContactRequestSignature {
func (m *ContactUpdate) GetContactRequestPropagatedState() *ContactRequestPropagatedState {
if m != nil {
return m.SentContactRequestSignature
}
return nil
}
func (m *ContactUpdate) GetReceivedContactRequestSignature() *ContactRequestSignature {
if m != nil {
return m.ReceivedContactRequestSignature
return m.ContactRequestPropagatedState
}
return nil
}
@ -119,7 +174,7 @@ func (m *AcceptContactRequest) Reset() { *m = AcceptContactRequest{} }
func (m *AcceptContactRequest) String() string { return proto.CompactTextString(m) }
func (*AcceptContactRequest) ProtoMessage() {}
func (*AcceptContactRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_a5036fff2565fb15, []int{1}
return fileDescriptor_a5036fff2565fb15, []int{2}
}
func (m *AcceptContactRequest) XXX_Unmarshal(b []byte) error {
@ -166,7 +221,7 @@ func (m *RetractContactRequest) Reset() { *m = RetractContactRequest{} }
func (m *RetractContactRequest) String() string { return proto.CompactTextString(m) }
func (*RetractContactRequest) ProtoMessage() {}
func (*RetractContactRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_a5036fff2565fb15, []int{2}
return fileDescriptor_a5036fff2565fb15, []int{3}
}
func (m *RetractContactRequest) XXX_Unmarshal(b []byte) error {
@ -202,6 +257,7 @@ func (m *RetractContactRequest) GetClock() uint64 {
}
func init() {
proto.RegisterType((*ContactRequestPropagatedState)(nil), "protobuf.ContactRequestPropagatedState")
proto.RegisterType((*ContactUpdate)(nil), "protobuf.ContactUpdate")
proto.RegisterType((*AcceptContactRequest)(nil), "protobuf.AcceptContactRequest")
proto.RegisterType((*RetractContactRequest)(nil), "protobuf.RetractContactRequest")
@ -212,25 +268,26 @@ func init() {
}
var fileDescriptor_a5036fff2565fb15 = []byte{
// 311 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x51, 0x31, 0x4f, 0xf3, 0x30,
0x14, 0x54, 0xd2, 0xf6, 0xfb, 0xda, 0xd7, 0xa6, 0x48, 0xa6, 0x95, 0x02, 0x48, 0xd0, 0x86, 0xa5,
0x53, 0x90, 0xca, 0x08, 0x0c, 0xd0, 0x89, 0x85, 0xc1, 0x88, 0x85, 0xc5, 0x72, 0x9d, 0xd7, 0x62,
0xd1, 0x38, 0xc1, 0x76, 0x91, 0xf8, 0x1f, 0xfc, 0x60, 0x54, 0x3b, 0x11, 0x50, 0xa9, 0x08, 0x31,
0x25, 0xbe, 0xbb, 0x77, 0xef, 0xec, 0x83, 0x48, 0x14, 0xca, 0x72, 0x61, 0xd3, 0x52, 0x17, 0xb6,
0x20, 0x6d, 0xf7, 0x99, 0xaf, 0x17, 0x87, 0x44, 0x3c, 0x71, 0xcb, 0x72, 0x34, 0x86, 0x2f, 0xd1,
0xb3, 0xc9, 0x7b, 0x03, 0xa2, 0x99, 0xd7, 0x3f, 0x94, 0x19, 0xb7, 0x48, 0x06, 0xd0, 0x12, 0xab,
0x42, 0x3c, 0xc7, 0xc1, 0x28, 0x98, 0x34, 0xa9, 0x3f, 0x90, 0x03, 0x68, 0xa3, 0x32, 0x4c, 0xf1,
0x1c, 0xe3, 0x70, 0x14, 0x4c, 0x3a, 0xf4, 0x3f, 0x2a, 0x73, 0xc7, 0x73, 0x24, 0xa7, 0x10, 0x95,
0xba, 0x58, 0xc8, 0x15, 0x32, 0x99, 0xf3, 0x25, 0xc6, 0x0d, 0xc7, 0xf7, 0x2a, 0xf0, 0x76, 0x83,
0x91, 0x31, 0xf4, 0x32, 0x69, 0xca, 0x15, 0x7f, 0xf3, 0x1e, 0x4d, 0xa7, 0xe9, 0x56, 0x98, 0xf3,
0x99, 0xc2, 0xb0, 0x4a, 0xce, 0x34, 0xbe, 0xac, 0xd1, 0x58, 0xe6, 0x83, 0xb4, 0x5c, 0x90, 0xfd,
0x8a, 0xa4, 0x9e, 0x9b, 0xb9, 0x58, 0x0b, 0x38, 0x36, 0xa8, 0x2c, 0xdb, 0x1e, 0x34, 0x72, 0xa9,
0xb8, 0x5d, 0x6b, 0x8c, 0xfb, 0xa3, 0x60, 0xd2, 0x9d, 0x8e, 0xd3, 0xfa, 0x15, 0xd2, 0xd9, 0x37,
0x9b, 0xfb, 0x5a, 0x48, 0x8f, 0x36, 0x46, 0x3b, 0x48, 0xa2, 0x20, 0xd1, 0x28, 0x50, 0xbe, 0x62,
0xf6, 0xc3, 0xae, 0xbd, 0xdf, 0xee, 0x3a, 0xa9, 0xcd, 0x76, 0x08, 0x92, 0x4b, 0x18, 0x5c, 0x0b,
0x81, 0xe5, 0x56, 0x20, 0xd2, 0x87, 0x50, 0x66, 0xae, 0x99, 0x0e, 0x0d, 0x65, 0xf6, 0x59, 0x56,
0xf8, 0xa5, 0xac, 0xe4, 0x0a, 0x86, 0x14, 0xad, 0xe6, 0xe2, 0x4f, 0xe3, 0x37, 0xd1, 0x63, 0x37,
0x3d, 0xbb, 0xa8, 0x2f, 0x31, 0xff, 0xe7, 0xfe, 0xce, 0x3f, 0x02, 0x00, 0x00, 0xff, 0xff, 0x8b,
0xda, 0xbb, 0xda, 0x58, 0x02, 0x00, 0x00,
// 329 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x91, 0xb1, 0x4e, 0xf3, 0x30,
0x14, 0x85, 0x95, 0xfc, 0x6d, 0xff, 0xe6, 0xa6, 0x61, 0x08, 0xad, 0x54, 0x86, 0x8a, 0x10, 0x06,
0x3a, 0x05, 0xa9, 0x8c, 0xc0, 0x00, 0x9d, 0x58, 0x10, 0x32, 0x62, 0x61, 0x89, 0x5c, 0xe7, 0xb6,
0x8a, 0x48, 0x62, 0xe3, 0xb8, 0x03, 0x4f, 0xc4, 0xc6, 0x33, 0xa2, 0xd8, 0x2e, 0x49, 0x19, 0x3a,
0x30, 0x25, 0x3e, 0x3e, 0xfe, 0x74, 0xee, 0xb9, 0x10, 0x30, 0x5e, 0x29, 0xca, 0x54, 0x22, 0x24,
0x57, 0x3c, 0x1c, 0xea, 0xcf, 0x6a, 0xbb, 0x8e, 0x3f, 0x1d, 0x98, 0x2d, 0xcd, 0x1d, 0xc1, 0xf7,
0x2d, 0xd6, 0xea, 0x49, 0x72, 0x41, 0x37, 0x54, 0x61, 0xf6, 0xac, 0xa8, 0xc2, 0xf0, 0x14, 0xfc,
0x82, 0x33, 0x5a, 0xa4, 0xac, 0xe0, 0xec, 0x6d, 0xea, 0x44, 0xce, 0xbc, 0x47, 0x40, 0x4b, 0xcb,
0x46, 0x69, 0x0d, 0x75, 0xe3, 0x9f, 0xba, 0x1d, 0x83, 0x21, 0x9c, 0xc1, 0x48, 0x62, 0xc9, 0x15,
0x5a, 0xc4, 0x3f, 0xed, 0xf0, 0x8d, 0x66, 0x18, 0xad, 0xc5, 0x40, 0x7a, 0x5d, 0x8b, 0xa6, 0xc4,
0x5f, 0x2e, 0x04, 0x36, 0xe9, 0x8b, 0xc8, 0x1a, 0xee, 0x18, 0xfa, 0xdd, 0x4c, 0xe6, 0x10, 0x9e,
0xc0, 0x10, 0xab, 0x3a, 0xad, 0x68, 0x69, 0xb2, 0x78, 0xe4, 0x3f, 0x56, 0xf5, 0x23, 0x2d, 0x31,
0x3c, 0x87, 0x40, 0x48, 0xbe, 0xce, 0x0b, 0x4c, 0xf3, 0x92, 0x6e, 0x50, 0x27, 0xf1, 0xc8, 0xc8,
0x8a, 0x0f, 0x8d, 0xd6, 0x44, 0xc9, 0xf2, 0x5a, 0x14, 0xf4, 0xc3, 0x30, 0x7a, 0xda, 0xe3, 0x5b,
0x4d, 0x73, 0x16, 0x30, 0xb1, 0x7d, 0xa6, 0xd2, 0x94, 0x66, 0x27, 0xeb, 0xeb, 0x20, 0xc7, 0x6c,
0xaf, 0x50, 0x33, 0xa1, 0x80, 0xe8, 0xf7, 0x1b, 0xf1, 0xd3, 0xb4, 0x9d, 0x7a, 0x10, 0x39, 0x73,
0x7f, 0x71, 0x91, 0xec, 0xb6, 0x93, 0x1c, 0xdc, 0x0c, 0x99, 0xb1, 0x43, 0xd7, 0xf1, 0x0d, 0x8c,
0xef, 0x18, 0x43, 0xa1, 0xf6, 0x29, 0xe1, 0x11, 0xb8, 0x79, 0xa6, 0x3b, 0xf3, 0x88, 0x9b, 0x67,
0x6d, 0x8d, 0x6e, 0xa7, 0xc6, 0xf8, 0x16, 0x26, 0x04, 0x95, 0xa4, 0xec, 0x4f, 0xcf, 0xef, 0x83,
0x57, 0x3f, 0xb9, 0xbc, 0xde, 0x0d, 0xb2, 0x1a, 0xe8, 0xbf, 0xab, 0xef, 0x00, 0x00, 0x00, 0xff,
0xff, 0xa0, 0x8b, 0xa7, 0x4a, 0x88, 0x02, 0x00, 0x00,
}

View File

@ -2,7 +2,13 @@ syntax = "proto3";
option go_package = "./;protobuf";
package protobuf;
import "chat_message.proto";
message ContactRequestPropagatedState {
uint64 local_clock = 1;
uint64 local_state = 2;
uint64 remote_clock = 3;
uint64 remote_state = 4;
}
message ContactUpdate {
uint64 clock = 1;
@ -10,9 +16,7 @@ message ContactUpdate {
string profile_image = 3;
string display_name = 4;
uint64 contact_request_clock = 5;
ContactRequestSignature sent_contact_request_signature = 14;
ContactRequestSignature received_contact_request_signature = 15;
ContactRequestPropagatedState contact_request_propagated_state = 6;
}
message AcceptContactRequest {