diff --git a/core/contact.go b/core/contact.go index 0987657..82f7afc 100644 --- a/core/contact.go +++ b/core/contact.go @@ -10,7 +10,6 @@ import ( connection "github.com/s-rah/go-ricochet/connection" "golang.org/x/net/context" "log" - "strconv" "sync" "time" ) @@ -18,7 +17,6 @@ import ( type Contact struct { core *Ricochet - id int data *ricochet.Contact mutex sync.Mutex @@ -35,19 +33,16 @@ type Contact struct { conversation *Conversation } -func ContactFromConfig(core *Ricochet, id int, data *ricochet.Contact, events *utils.Publisher) (*Contact, error) { +func ContactFromConfig(core *Ricochet, data *ricochet.Contact, events *utils.Publisher) (*Contact, error) { contact := &Contact{ core: core, - id: id, data: data, events: events, connChannel: make(chan *connection.Connection), connEnabledSignal: make(chan bool), } - if id < 0 { - return nil, fmt.Errorf("Invalid contact ID '%d'", id) - } else if !IsAddressValid(data.Address) { + if !IsAddressValid(data.Address) { return nil, fmt.Errorf("Invalid contact address '%s", data.Address) } @@ -64,10 +59,6 @@ func ContactFromConfig(core *Ricochet, id int, data *ricochet.Contact, events *u return contact, nil } -func (c *Contact) Id() int { - return c.id -} - func (c *Contact) Nickname() string { c.mutex.Lock() defer c.mutex.Unlock() @@ -124,8 +115,7 @@ func (c *Contact) Conversation() *Conversation { defer c.mutex.Unlock() if c.conversation == nil { entity := &ricochet.Entity{ - ContactId: int32(c.id), - Address: c.data.Address, + Address: c.data.Address, } c.conversation = NewConversation(c, entity, c.core.Identity.ConversationStream) } @@ -536,7 +526,7 @@ func (c *Contact) onConnectionStateChanged() { c.data.LastConnected = c.timeConnected.Format(time.RFC3339) config := c.core.Config.Lock() - config.Contacts[strconv.Itoa(c.id)] = c.data + config.Contacts[c.data.Address] = c.data c.core.Config.Unlock() // XXX I wonder if events and config updates can be combined now, and made safer... @@ -644,7 +634,7 @@ func (c *Contact) updateContactRequest(status string) bool { config := c.core.Config.Lock() defer c.core.Config.Unlock() - config.Contacts[strconv.Itoa(c.id)] = c.data + config.Contacts[c.data.Address] = c.data return re } diff --git a/core/contactlist.go b/core/contactlist.go index 4e904b5..9d3466d 100644 --- a/core/contactlist.go +++ b/core/contactlist.go @@ -5,7 +5,6 @@ import ( "fmt" "github.com/ricochet-im/ricochet-go/core/utils" "github.com/ricochet-im/ricochet-go/rpc" - "strconv" "sync" "time" ) @@ -16,7 +15,7 @@ type ContactList struct { mutex sync.RWMutex events *utils.Publisher - contacts map[int]*Contact + contacts map[string]*Contact inboundRequests map[string]*InboundContactRequest } @@ -28,21 +27,20 @@ func LoadContactList(core *Ricochet) (*ContactList, error) { } config := core.Config.Read() - list.contacts = make(map[int]*Contact, len(config.Contacts)) - for idStr, data := range config.Contacts { - id, err := strconv.Atoi(idStr) - if err != nil { - return nil, fmt.Errorf("Invalid contact id '%s'", idStr) + list.contacts = make(map[string]*Contact, len(config.Contacts)) + for addr, data := range config.Contacts { + if _, exists := list.contacts[addr]; exists { + return nil, fmt.Errorf("Duplicate contact %s", addr) } - if _, exists := list.contacts[id]; exists { - return nil, fmt.Errorf("Duplicate contact id '%d'", id) + if addr != data.Address { + return nil, fmt.Errorf("Contact address/key do not match ('%s' and '%s')", addr, data.Address) } - contact, err := ContactFromConfig(core, id, data, list.events) + contact, err := ContactFromConfig(core, data, list.events) if err != nil { return nil, err } - list.contacts[id] = contact + list.contacts[addr] = contact } return list, nil @@ -62,32 +60,16 @@ func (this *ContactList) Contacts() []*Contact { return re } -func (this *ContactList) ContactById(id int) *Contact { - this.mutex.RLock() - defer this.mutex.RUnlock() - return this.contacts[id] -} - -func (this *ContactList) ContactByAddress(address string) *Contact { - this.mutex.RLock() - defer this.mutex.RUnlock() - for _, contact := range this.contacts { - if contact.Address() == address { - return contact - } - } - return nil +func (cl *ContactList) ContactByAddress(address string) *Contact { + cl.mutex.RLock() + defer cl.mutex.RUnlock() + return cl.contacts[address] } func (cl *ContactList) InboundRequestByAddress(address string) *InboundContactRequest { cl.mutex.RLock() defer cl.mutex.RUnlock() - for _, request := range cl.inboundRequests { - if request.Address == address { - return request - } - } - return nil + return cl.inboundRequests[address] } // AddNewContact adds a new contact to the persistent contact list, broadcasts a @@ -101,10 +83,10 @@ func (this *ContactList) AddNewContact(data *ricochet.Contact) (*Contact, error) this.mutex.Lock() defer this.mutex.Unlock() + if this.contacts[data.Address] != nil { + return nil, errors.New("Contact already exists with this address") + } for _, contact := range this.contacts { - if contact.Address() == data.Address { - return nil, errors.New("Contact already exists with this address") - } if contact.Nickname() == data.Nickname { return nil, errors.New("Contact already exists with this nickname") } @@ -114,30 +96,18 @@ func (this *ContactList) AddNewContact(data *ricochet.Contact) (*Contact, error) // Write new contact into config config := this.core.Config.Lock() - - maxContactId := 0 - for idstr, _ := range config.Contacts { - if id, err := strconv.Atoi(idstr); err == nil { - if maxContactId < id { - maxContactId = id - } - } - } - - contactId := maxContactId + 1 - if config.Contacts == nil { config.Contacts = make(map[string]*ricochet.Contact) } - config.Contacts[strconv.Itoa(contactId)] = data + config.Contacts[data.Address] = data this.core.Config.Unlock() // Create Contact - contact, err := ContactFromConfig(this.core, contactId, data, this.events) + contact, err := ContactFromConfig(this.core, data, this.events) if err != nil { return nil, err } - this.contacts[contactId] = contact + this.contacts[data.Address] = contact event := ricochet.ContactEvent{ Type: ricochet.ContactEvent_ADD, @@ -201,7 +171,8 @@ func (this *ContactList) RemoveContact(contact *Contact) error { this.mutex.Lock() defer this.mutex.Unlock() - if this.contacts[contact.Id()] != contact { + address := contact.Address() + if this.contacts[address] != contact { return errors.New("Not in contact list") } @@ -211,17 +182,16 @@ func (this *ContactList) RemoveContact(contact *Contact) error { contact.StopConnection() config := this.core.Config.Lock() - delete(config.Contacts, strconv.Itoa(contact.Id())) + delete(config.Contacts, address) this.core.Config.Unlock() - delete(this.contacts, contact.Id()) + delete(this.contacts, address) event := ricochet.ContactEvent{ Type: ricochet.ContactEvent_DELETE, Subject: &ricochet.ContactEvent_Contact{ Contact: &ricochet.Contact{ - Id: int32(contact.Id()), - Address: contact.Address(), + Address: address, }, }, } diff --git a/core/rpcserver.go b/core/rpcserver.go index 41c269c..40ea5ec 100644 --- a/core/rpcserver.go +++ b/core/rpcserver.go @@ -139,7 +139,7 @@ func (s *RpcServer) UpdateContact(ctx context.Context, req *ricochet.Contact) (* func (s *RpcServer) DeleteContact(ctx context.Context, req *ricochet.DeleteContactRequest) (*ricochet.DeleteContactReply, error) { contactList := s.Core.Identity.ContactList() contact := contactList.ContactByAddress(req.Address) - if contact == nil || (req.Id != 0 && contact.Id() != int(req.Id)) { + if contact == nil { return nil, errors.New("Contact not found") } @@ -239,7 +239,7 @@ func (s *RpcServer) SendMessage(ctx context.Context, req *ricochet.Message) (*ri } contact := s.Core.Identity.ContactList().ContactByAddress(req.Recipient.Address) - if contact == nil || (req.Recipient.ContactId != 0 && int32(contact.Id()) != req.Recipient.ContactId) { + if contact == nil { return nil, errors.New("Unknown recipient") } @@ -261,7 +261,7 @@ func (s *RpcServer) MarkConversationRead(ctx context.Context, req *ricochet.Mark } contact := s.Core.Identity.ContactList().ContactByAddress(req.Entity.Address) - if contact == nil || (req.Entity.ContactId != 0 && int32(contact.Id()) != req.Entity.ContactId) { + if contact == nil { return nil, errors.New("Unknown entity") } diff --git a/ricochet-cli/client.go b/ricochet-cli/client.go index ce4de47..6588dd7 100644 --- a/ricochet-cli/client.go +++ b/ricochet-cli/client.go @@ -211,7 +211,7 @@ func (c *Client) onContactEvent(event *ricochet.ContactEvent) { return } - contact := c.Contacts.ByIdAndAddress(data.Id, data.Address) + contact := c.Contacts.ByAddress(data.Address) if contact == nil { log.Printf("Ignoring contact update event for unknown contact: %v", data) } else { @@ -257,7 +257,7 @@ func (c *Client) onConversationEvent(event *ricochet.ConversationEvent) { remoteEntity = message.Recipient } - remoteContact := c.Contacts.ByIdAndAddress(remoteEntity.ContactId, remoteEntity.Address) + remoteContact := c.Contacts.ByAddress(remoteEntity.Address) if remoteContact == nil { log.Printf("Ignoring conversation event with unknown contact: %v", event) return diff --git a/ricochet-cli/contact.go b/ricochet-cli/contact.go index 996a7fe..e0a8fec 100644 --- a/ricochet-cli/contact.go +++ b/ricochet-cli/contact.go @@ -8,60 +8,48 @@ import ( type ContactList struct { Client *Client - Contacts map[int32]*Contact + Contacts map[string]*Contact } func NewContactList(client *Client) *ContactList { return &ContactList{ Client: client, - Contacts: make(map[int32]*Contact), + Contacts: make(map[string]*Contact), } } func (cl *ContactList) Populate(data *ricochet.Contact) error { - if cl.Contacts[data.Id] != nil { - return fmt.Errorf("Duplicate contact ID %d in populate", data.Id) + if cl.Contacts[data.Address] != nil { + return fmt.Errorf("Duplicate contact %s in populate", data.Address) } - cl.Contacts[data.Id] = initContact(cl.Client, data) + cl.Contacts[data.Address] = initContact(cl.Client, data) return nil } func (cl *ContactList) Added(data *ricochet.Contact) (*Contact, error) { - if cl.Contacts[data.Id] != nil { - return nil, fmt.Errorf("Duplicate contact ID %d in add", data.Id) + if cl.Contacts[data.Address] != nil { + return nil, fmt.Errorf("Duplicate contact %s in add", data.Address) } contact := initContact(cl.Client, data) - cl.Contacts[data.Id] = contact + cl.Contacts[data.Address] = contact return contact, nil } func (cl *ContactList) Deleted(data *ricochet.Contact) (*Contact, error) { - contact := cl.Contacts[data.Id] + contact := cl.Contacts[data.Address] if contact == nil { - return nil, fmt.Errorf("Contact ID %d does not exist in delete", data.Id) - } - - if contact.Data.Address != data.Address { - return nil, fmt.Errorf("Contact ID %d does not match address in delete (expected %s, received %s)", data.Id, contact.Data.Address, data.Address) + return nil, fmt.Errorf("Contact %s does not exist in delete", data.Address) } contact.Deleted() - delete(cl.Contacts, data.Id) + delete(cl.Contacts, data.Address) return contact, nil } -func (cl *ContactList) ById(id int32) *Contact { - return cl.Contacts[id] -} - -func (cl *ContactList) ByIdAndAddress(id int32, address string) *Contact { - contact := cl.Contacts[id] - if contact != nil && contact.Data.Address == address { - return contact - } - return nil +func (cl *ContactList) ByAddress(address string) *Contact { + return cl.Contacts[address] } type Contact struct { @@ -81,8 +69,8 @@ func initContact(client *Client, data *ricochet.Contact) *Contact { } func (c *Contact) Updated(newData *ricochet.Contact) error { - if newData.Id != c.Data.Id || newData.Address != c.Data.Address { - return errors.New("Contact ID and address are immutable") + if newData.Address != c.Data.Address { + return errors.New("Contact address is immutable") } c.Data = newData @@ -91,7 +79,6 @@ func (c *Contact) Updated(newData *ricochet.Contact) error { func (c *Contact) Deleted() { c.Data = &ricochet.Contact{ - Id: c.Data.Id, Address: c.Data.Address, } } diff --git a/ricochet-cli/conversation.go b/ricochet-cli/conversation.go index c597a3b..fb0e301 100644 --- a/ricochet-cli/conversation.go +++ b/ricochet-cli/conversation.go @@ -35,12 +35,9 @@ type Conversation struct { // conversation backlog. Blocking API call. func (c *Conversation) SendMessage(text string) error { msg, err := c.Client.Backend.SendMessage(context.Background(), &ricochet.Message{ - Sender: &ricochet.Entity{IsSelf: true}, - Recipient: &ricochet.Entity{ - ContactId: c.Contact.Data.Id, - Address: c.Contact.Data.Address, - }, - Text: text, + Sender: &ricochet.Entity{IsSelf: true}, + Recipient: &ricochet.Entity{Address: c.Contact.Data.Address}, + Text: text, }) if err != nil { fmt.Fprintf(Ui.Stdout, "send message error: %v\n", err) @@ -213,13 +210,12 @@ func (c *Conversation) validateMessage(msg *ricochet.Message) error { remoteEntity = msg.Sender } - if !localEntity.IsSelf || localEntity.ContactId != 0 || + if !localEntity.IsSelf || (len(localEntity.Address) > 0 && localEntity.Address != c.Client.Identity.Address) { return fmt.Errorf("Invalid self entity on message: %v", localEntity) } - if remoteEntity.IsSelf || remoteEntity.ContactId != c.Contact.Data.Id || - remoteEntity.Address != c.Contact.Data.Address { + if remoteEntity.IsSelf || remoteEntity.Address != c.Contact.Data.Address { return fmt.Errorf("Invalid remote entity on message: %v", remoteEntity) } diff --git a/ricochet-cli/ui.go b/ricochet-cli/ui.go index b811c33..03eed0f 100644 --- a/ricochet-cli/ui.go +++ b/ricochet-cli/ui.go @@ -8,7 +8,6 @@ import ( "github.com/ricochet-im/ricochet-go/rpc" "golang.org/x/net/context" "io" - "strconv" "strings" "time" ) @@ -227,20 +226,15 @@ func (ui *UI) AddContact(params []string) { return } - fmt.Fprintf(ui.Stdout, "Added contact \x1b[1m%s\x1b[0m (\x1b[1m%d\x1b[0m)\n", contact.Nickname, contact.Id) + fmt.Fprintf(ui.Stdout, "Added contact \x1b[1m%s\x1b[0m (\x1b[1m%s\x1b[0m)\n", contact.Nickname, contact.Address) } func (ui *UI) DeleteContact(params []string) { if len(params) < 1 { - fmt.Fprintf(ui.Stdout, "Usage: delete-contact [id]\n") + fmt.Fprintf(ui.Stdout, "Usage: delete-contact [address]\n") return } - id, err := strconv.Atoi(params[0]) - if err != nil { - fmt.Fprintf(ui.Stdout, "Invalid contact id '%s'\n", params[0]) - return - } - contact := ui.Client.Contacts.ById(int32(id)) + contact := ui.Client.Contacts.ByAddress(params[0]) if contact == nil { contact = ui.ContactByPrefix(params[0]) } @@ -261,10 +255,7 @@ func (ui *UI) DeleteContact(params []string) { } _, err = ui.Client.Backend.DeleteContact(context.Background(), - &ricochet.DeleteContactRequest{ - Id: contact.Data.Id, - Address: contact.Data.Address, - }) + &ricochet.DeleteContactRequest{Address: contact.Data.Address}) if err != nil { fmt.Fprintf(ui.Stdout, "Failed: %s\n", err) return diff --git a/rpc/contact.pb.go b/rpc/contact.pb.go index dcb08c7..6861ec2 100644 --- a/rpc/contact.pb.go +++ b/rpc/contact.pb.go @@ -141,7 +141,6 @@ func (x ContactEvent_Type) String() string { func (ContactEvent_Type) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{3, 0} } type Contact struct { - Id int32 `protobuf:"varint,1,opt,name=id" json:"id,omitempty"` Address string `protobuf:"bytes,2,opt,name=address" json:"address,omitempty"` Nickname string `protobuf:"bytes,3,opt,name=nickname" json:"nickname,omitempty"` WhenCreated string `protobuf:"bytes,4,opt,name=whenCreated" json:"whenCreated,omitempty"` @@ -155,13 +154,6 @@ func (m *Contact) String() string { return proto.CompactTextString(m) func (*Contact) ProtoMessage() {} func (*Contact) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } -func (m *Contact) GetId() int32 { - if m != nil { - return m.Id - } - return 0 -} - func (m *Contact) GetAddress() string { if m != nil { return m.Address @@ -438,8 +430,7 @@ func (*AddContactReply) ProtoMessage() {} func (*AddContactReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} } type DeleteContactRequest struct { - Id int32 `protobuf:"varint,1,opt,name=id" json:"id,omitempty"` - Address string `protobuf:"bytes,2,opt,name=address" json:"address,omitempty"` + Address string `protobuf:"bytes,1,opt,name=address" json:"address,omitempty"` } func (m *DeleteContactRequest) Reset() { *m = DeleteContactRequest{} } @@ -447,13 +438,6 @@ func (m *DeleteContactRequest) String() string { return proto.Compact func (*DeleteContactRequest) ProtoMessage() {} func (*DeleteContactRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} } -func (m *DeleteContactRequest) GetId() int32 { - if m != nil { - return m.Id - } - return 0 -} - func (m *DeleteContactRequest) GetAddress() string { if m != nil { return m.Address @@ -494,42 +478,41 @@ func init() { func init() { proto.RegisterFile("contact.proto", fileDescriptor0) } var fileDescriptor0 = []byte{ - // 581 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x9c, 0x54, 0xdd, 0x6e, 0xd3, 0x30, - 0x14, 0x5e, 0xda, 0x2c, 0x3f, 0xa7, 0x5b, 0xc9, 0xac, 0x09, 0x85, 0xed, 0x26, 0xb2, 0x10, 0xea, - 0x0d, 0x01, 0x15, 0xee, 0xd9, 0xd6, 0x64, 0xa2, 0x50, 0x92, 0xe1, 0x25, 0xe2, 0x3a, 0x4b, 0x8c, - 0x16, 0xe8, 0xe2, 0xe2, 0xb8, 0x83, 0xbd, 0x06, 0x4f, 0xc5, 0xe3, 0xf0, 0x08, 0xc8, 0x4e, 0xd2, - 0xad, 0x2b, 0x20, 0xc4, 0x9d, 0xcf, 0x77, 0xbe, 0x63, 0x1f, 0x7f, 0xdf, 0xb1, 0x61, 0x37, 0x67, - 0x95, 0xc8, 0x72, 0xe1, 0x2f, 0x38, 0x13, 0x0c, 0x59, 0xbc, 0xcc, 0x59, 0x7e, 0x49, 0x05, 0xfe, - 0xd1, 0x03, 0x73, 0xd2, 0xe4, 0xd0, 0x10, 0x7a, 0x65, 0xe1, 0x6a, 0x9e, 0x36, 0xda, 0x26, 0xbd, - 0xb2, 0x40, 0x2e, 0x98, 0x59, 0x51, 0x70, 0x5a, 0xd7, 0x6e, 0xcf, 0xd3, 0x46, 0x36, 0xe9, 0x42, - 0x74, 0x00, 0x56, 0x55, 0xe6, 0x9f, 0xab, 0xec, 0x8a, 0xba, 0x7d, 0x95, 0x5a, 0xc5, 0xc8, 0x83, - 0xc1, 0xd7, 0x4b, 0x5a, 0x4d, 0x38, 0xcd, 0x04, 0x2d, 0x5c, 0x5d, 0xa5, 0xef, 0x42, 0xe8, 0x31, - 0xec, 0xce, 0xb3, 0x5a, 0x4c, 0x58, 0x55, 0xd1, 0x5c, 0x72, 0xb6, 0x15, 0x67, 0x1d, 0x44, 0x63, - 0x30, 0x39, 0xfd, 0xb2, 0xa4, 0xb5, 0x70, 0x0d, 0x4f, 0x1b, 0x0d, 0xc6, 0xae, 0xdf, 0x75, 0xed, - 0xb7, 0x1d, 0x93, 0x26, 0x4f, 0x3a, 0x22, 0x7a, 0x0e, 0x46, 0x2d, 0x32, 0xb1, 0xac, 0x5d, 0xf0, - 0xb4, 0xd1, 0xf0, 0x37, 0x25, 0xfe, 0xb9, 0xca, 0x93, 0x96, 0x87, 0xa7, 0x60, 0x34, 0x08, 0x1a, - 0x80, 0x99, 0x46, 0x6f, 0xa3, 0xf8, 0x43, 0xe4, 0x6c, 0xc9, 0x20, 0x3e, 0x3d, 0x9d, 0x4d, 0xa3, - 0xd0, 0xd1, 0x10, 0x80, 0x11, 0x47, 0x6a, 0xdd, 0x93, 0x09, 0x12, 0xbe, 0x4f, 0xc3, 0xf3, 0xc4, - 0xe9, 0xa3, 0x1d, 0xb0, 0x48, 0xf8, 0x26, 0x9c, 0x24, 0x61, 0xe0, 0xe8, 0xf8, 0x7b, 0x1f, 0x86, - 0xeb, 0x8d, 0xa1, 0x23, 0xb0, 0x8b, 0x92, 0xd3, 0x5c, 0x94, 0xac, 0x52, 0xc2, 0x0e, 0xc7, 0xf8, - 0x4f, 0xb7, 0xf0, 0x83, 0x8e, 0x49, 0x6e, 0x8b, 0xfe, 0xd3, 0x03, 0x04, 0xba, 0xa0, 0xdf, 0x44, - 0x2b, 0xbe, 0x5a, 0x23, 0x0c, 0x3b, 0x1f, 0x39, 0xbb, 0x8a, 0xba, 0x9a, 0x46, 0xf4, 0x35, 0xec, - 0xbe, 0x77, 0xc6, 0xa6, 0x77, 0x07, 0x60, 0x71, 0xfa, 0xa9, 0xb1, 0xcd, 0xf4, 0xb4, 0x91, 0x45, - 0x56, 0xb1, 0xf4, 0x55, 0x52, 0x03, 0x3a, 0x2f, 0xaf, 0x29, 0xa7, 0x85, 0x6b, 0x35, 0xbe, 0xae, - 0x81, 0xb2, 0x0f, 0x09, 0x90, 0x6e, 0x17, 0xbb, 0xe9, 0xe3, 0x2e, 0x26, 0xfb, 0xe0, 0xf4, 0x8a, - 0x09, 0x1a, 0x72, 0xce, 0xb8, 0x32, 0xd3, 0x26, 0x77, 0x21, 0xfc, 0x04, 0xec, 0x95, 0x5e, 0xd2, - 0x94, 0x69, 0x74, 0x12, 0xa7, 0x51, 0xe0, 0x6c, 0x49, 0x53, 0xe2, 0x34, 0x69, 0x22, 0x0d, 0xbb, - 0xf0, 0xf0, 0x1d, 0xab, 0x4a, 0xc1, 0x78, 0xab, 0x76, 0xdd, 0xca, 0x8d, 0x7f, 0x6a, 0xb0, 0xd3, - 0x62, 0xe1, 0x35, 0xad, 0x04, 0x7a, 0x06, 0xba, 0xb8, 0x59, 0xd0, 0xd6, 0xa7, 0xc3, 0x0d, 0x9f, - 0x14, 0xcb, 0x4f, 0x6e, 0x16, 0x94, 0x28, 0x22, 0x7a, 0x0a, 0x66, 0xfb, 0xac, 0x94, 0x37, 0x83, - 0xf1, 0xde, 0x46, 0xcd, 0xeb, 0x2d, 0xd2, 0x71, 0xd0, 0xcb, 0xdb, 0x81, 0xee, 0xff, 0x7d, 0xa0, - 0x65, 0x55, 0x4b, 0xc5, 0xaf, 0x40, 0x97, 0x47, 0x22, 0x0b, 0xf4, 0x28, 0x9d, 0xcd, 0x9a, 0x0b, - 0x9e, 0xc5, 0x67, 0xe9, 0xec, 0x38, 0x91, 0xc3, 0x69, 0x42, 0xff, 0x38, 0x08, 0x9c, 0x9e, 0x9c, - 0xd2, 0xf4, 0x2c, 0x90, 0x60, 0x5f, 0xae, 0x83, 0x70, 0x16, 0x26, 0xa1, 0xa3, 0x9f, 0xd8, 0x60, - 0xd6, 0xcb, 0x0b, 0x29, 0x2c, 0xde, 0x83, 0x07, 0xc7, 0x45, 0xb1, 0x3a, 0x6b, 0x31, 0xbf, 0xc1, - 0x47, 0xb0, 0x1f, 0xd0, 0x39, 0x15, 0xf4, 0xde, 0xe4, 0xfe, 0xf3, 0x5f, 0x80, 0xf7, 0x01, 0xdd, - 0xdb, 0x41, 0xee, 0x7b, 0x08, 0x8f, 0x1a, 0x37, 0xa7, 0xd5, 0x05, 0x5b, 0x56, 0x45, 0xf7, 0x54, - 0x65, 0xf2, 0xc2, 0x50, 0xbf, 0xd0, 0x8b, 0x5f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x13, 0x18, 0x1c, - 0x90, 0x96, 0x04, 0x00, 0x00, + // 569 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x9c, 0x54, 0x5d, 0x73, 0x93, 0x40, + 0x14, 0x2d, 0x01, 0xf9, 0xb8, 0x69, 0x2b, 0xdd, 0xe9, 0x38, 0xd8, 0xbe, 0x64, 0x76, 0x1c, 0x27, + 0x2f, 0x62, 0xa7, 0xfa, 0xae, 0x6d, 0xa0, 0x63, 0x34, 0x42, 0xdd, 0xc2, 0xf8, 0x4c, 0x61, 0x9d, + 0xa2, 0x29, 0x1b, 0x97, 0x4d, 0x35, 0x7f, 0xc3, 0x5f, 0xe3, 0xcf, 0xf2, 0x27, 0x38, 0xbb, 0x40, + 0x9a, 0x0f, 0xf5, 0xc1, 0xb7, 0xbd, 0xe7, 0x9e, 0x0b, 0x87, 0x7b, 0xce, 0x02, 0x7b, 0x39, 0xab, + 0x44, 0x96, 0x0b, 0x7f, 0xc6, 0x99, 0x60, 0xc8, 0xe6, 0x65, 0xce, 0xf2, 0x1b, 0x2a, 0xf0, 0xcf, + 0x1e, 0x58, 0xa3, 0xa6, 0x87, 0x3c, 0xb0, 0xb2, 0xa2, 0xe0, 0xb4, 0xae, 0xbd, 0xde, 0x40, 0x1b, + 0x3a, 0xa4, 0x2b, 0xd1, 0x11, 0xd8, 0x55, 0x99, 0x7f, 0xa9, 0xb2, 0x5b, 0xea, 0xe9, 0xaa, 0xb5, + 0xac, 0xd1, 0x00, 0xfa, 0xdf, 0x6e, 0x68, 0x35, 0xe2, 0x34, 0x13, 0xb4, 0xf0, 0x0c, 0xd5, 0x5e, + 0x85, 0xd0, 0x13, 0xd8, 0x9b, 0x66, 0xb5, 0x18, 0xb1, 0xaa, 0xa2, 0xb9, 0xe4, 0x3c, 0x50, 0x9c, + 0x75, 0x10, 0x9d, 0x82, 0xc5, 0xe9, 0xd7, 0x39, 0xad, 0x85, 0x67, 0x0e, 0xb4, 0x61, 0xff, 0xd4, + 0xf3, 0x3b, 0x95, 0x7e, 0xab, 0x90, 0x34, 0x7d, 0xd2, 0x11, 0xd1, 0x09, 0x98, 0xb5, 0xc8, 0xc4, + 0xbc, 0xf6, 0x60, 0xa0, 0x0d, 0xf7, 0xff, 0x30, 0xe2, 0x5f, 0xa9, 0x3e, 0x69, 0x79, 0x78, 0x0c, + 0x66, 0x83, 0xa0, 0x3e, 0x58, 0x69, 0xf4, 0x2e, 0x8a, 0x3f, 0x46, 0xee, 0x8e, 0x2c, 0xe2, 0x8b, + 0x8b, 0xc9, 0x38, 0x0a, 0x5d, 0x0d, 0x01, 0x98, 0x71, 0xa4, 0xce, 0x3d, 0xd9, 0x20, 0xe1, 0x87, + 0x34, 0xbc, 0x4a, 0x5c, 0x1d, 0xed, 0x82, 0x4d, 0xc2, 0xb7, 0xe1, 0x28, 0x09, 0x03, 0xd7, 0xc0, + 0x3f, 0x74, 0xd8, 0x5f, 0x17, 0x86, 0x5e, 0x83, 0x53, 0x94, 0x9c, 0xe6, 0xa2, 0x64, 0x95, 0xa7, + 0x29, 0x49, 0xf8, 0x6f, 0x5f, 0xe1, 0x07, 0x1d, 0x93, 0xdc, 0x0f, 0xfd, 0xa7, 0x07, 0x08, 0x0c, + 0x41, 0xbf, 0x8b, 0x76, 0xf9, 0xea, 0x8c, 0x30, 0xec, 0x7e, 0xe2, 0xec, 0x36, 0xea, 0x66, 0x9a, + 0xa5, 0xaf, 0x61, 0x9b, 0xde, 0x99, 0xdb, 0xde, 0x1d, 0x81, 0xcd, 0xe9, 0xe7, 0xc6, 0x36, 0x6b, + 0xa0, 0x0d, 0x6d, 0xb2, 0xac, 0xa5, 0xaf, 0x92, 0x1a, 0xd0, 0x69, 0x79, 0x47, 0x39, 0x2d, 0x3c, + 0xbb, 0xf1, 0x75, 0x0d, 0x94, 0x3a, 0x24, 0x40, 0xba, 0xa7, 0x38, 0x8d, 0x8e, 0x55, 0x4c, 0xea, + 0xe0, 0xf4, 0x96, 0x09, 0x1a, 0x72, 0xce, 0xb8, 0x32, 0xd3, 0x21, 0xab, 0x10, 0x7e, 0x0a, 0xce, + 0x72, 0x5f, 0xd2, 0x94, 0x71, 0x74, 0x1e, 0xa7, 0x51, 0xe0, 0xee, 0x48, 0x53, 0xe2, 0x34, 0x69, + 0x2a, 0x0d, 0x7b, 0xf0, 0xe8, 0x3d, 0xab, 0x4a, 0xc1, 0x78, 0xbb, 0xed, 0xba, 0x5d, 0x37, 0xfe, + 0xa5, 0xc1, 0x6e, 0x8b, 0x85, 0x77, 0xb4, 0x12, 0xe8, 0x39, 0x18, 0x62, 0x31, 0xa3, 0xad, 0x4f, + 0xc7, 0x5b, 0x3e, 0x29, 0x96, 0x9f, 0x2c, 0x66, 0x94, 0x28, 0x22, 0x7a, 0x06, 0x56, 0x7b, 0x8d, + 0x94, 0x37, 0xfd, 0xd3, 0x83, 0xad, 0x99, 0x37, 0x3b, 0xa4, 0xe3, 0xa0, 0x97, 0xf7, 0x81, 0xd6, + 0xff, 0x1d, 0x68, 0x39, 0xd5, 0x52, 0xf1, 0x2b, 0x30, 0xe4, 0x2b, 0x91, 0x0d, 0x46, 0x94, 0x4e, + 0x26, 0xcd, 0x07, 0x5e, 0xc6, 0x97, 0xe9, 0xe4, 0x2c, 0x91, 0xe1, 0xb4, 0x40, 0x3f, 0x0b, 0x02, + 0xb7, 0x27, 0x53, 0x9a, 0x5e, 0x06, 0x12, 0xd4, 0xe5, 0x39, 0x08, 0x27, 0x61, 0x12, 0xba, 0xc6, + 0xb9, 0x03, 0x56, 0x3d, 0xbf, 0x96, 0x8b, 0xc5, 0x07, 0xf0, 0xf0, 0xac, 0x28, 0x96, 0xef, 0x9a, + 0x4d, 0x17, 0xf8, 0x04, 0x0e, 0x03, 0x3a, 0xa5, 0x82, 0x6e, 0x24, 0x77, 0x25, 0x77, 0xda, 0x5a, + 0xee, 0xf0, 0x21, 0xa0, 0x8d, 0x09, 0xf9, 0x9c, 0x63, 0x78, 0xdc, 0xb8, 0x37, 0xae, 0xae, 0xd9, + 0xbc, 0x2a, 0xba, 0xab, 0x29, 0x9b, 0xd7, 0xa6, 0xfa, 0xcb, 0xbc, 0xf8, 0x1d, 0x00, 0x00, 0xff, + 0xff, 0x2d, 0x76, 0xf2, 0x61, 0x76, 0x04, 0x00, 0x00, } diff --git a/rpc/contact.proto b/rpc/contact.proto index eeb3f37..dfb5677 100644 --- a/rpc/contact.proto +++ b/rpc/contact.proto @@ -1,11 +1,7 @@ syntax = "proto3"; package ricochet; -// XXX Using integer contact IDs seems dangerous, and it's especially a -// problem that 0 is a valid contact ID. Switch to UUID? Or use address? - message Contact { - int32 id = 1; string address = 2; string nickname = 3; string whenCreated = 4; @@ -62,8 +58,7 @@ message AddContactReply { } message DeleteContactRequest { - int32 id = 1; - string address = 2; + string address = 1; } message DeleteContactReply { diff --git a/rpc/conversation.pb.go b/rpc/conversation.pb.go index 8dfa931..2d06df3 100644 --- a/rpc/conversation.pb.go +++ b/rpc/conversation.pb.go @@ -114,10 +114,9 @@ func (*MonitorConversationsRequest) ProtoMessage() {} func (*MonitorConversationsRequest) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{1} } type Entity struct { - // contactId and address MAY be unspecified for self - ContactId int32 `protobuf:"varint,1,opt,name=contactId" json:"contactId,omitempty"` - Address string `protobuf:"bytes,2,opt,name=address" json:"address,omitempty"` - IsSelf bool `protobuf:"varint,3,opt,name=isSelf" json:"isSelf,omitempty"` + // address MAY be unspecified for self + Address string `protobuf:"bytes,2,opt,name=address" json:"address,omitempty"` + IsSelf bool `protobuf:"varint,3,opt,name=isSelf" json:"isSelf,omitempty"` } func (m *Entity) Reset() { *m = Entity{} } @@ -125,13 +124,6 @@ func (m *Entity) String() string { return proto.CompactTextString(m) func (*Entity) ProtoMessage() {} func (*Entity) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{2} } -func (m *Entity) GetContactId() int32 { - if m != nil { - return m.ContactId - } - return 0 -} - func (m *Entity) GetAddress() string { if m != nil { return m.Address @@ -242,35 +234,34 @@ func init() { func init() { proto.RegisterFile("conversation.proto", fileDescriptor1) } var fileDescriptor1 = []byte{ - // 467 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x74, 0x92, 0xd1, 0x6e, 0xd3, 0x4c, - 0x10, 0x85, 0x7f, 0x27, 0x8e, 0x93, 0x4c, 0x7e, 0xd0, 0x76, 0x2e, 0x90, 0xa5, 0x02, 0x8a, 0xcc, - 0x4d, 0xae, 0x2c, 0x14, 0x78, 0x81, 0xa8, 0x5e, 0xa1, 0x48, 0x49, 0x1a, 0x36, 0x4d, 0x85, 0xc4, - 0x95, 0xb1, 0xa7, 0x65, 0x45, 0x63, 0x07, 0xef, 0x34, 0x90, 0xc7, 0xe2, 0x1d, 0x78, 0x30, 0xb4, - 0x1b, 0x57, 0xb6, 0x14, 0xb8, 0xdb, 0x9d, 0xf3, 0xed, 0x78, 0xe6, 0x1c, 0x03, 0x66, 0x65, 0x71, - 0xa0, 0xca, 0xa4, 0xac, 0xcb, 0x22, 0xde, 0x57, 0x25, 0x97, 0x38, 0xa8, 0x74, 0x56, 0x66, 0x5f, - 0x89, 0xa3, 0x5f, 0x1e, 0x5c, 0x5c, 0xb5, 0x00, 0x79, 0xa0, 0x82, 0xf1, 0x3d, 0xf8, 0x7c, 0xdc, - 0x53, 0xe8, 0x8d, 0xbd, 0xc9, 0xf3, 0xe9, 0x38, 0x7e, 0xc2, 0xe3, 0x33, 0x34, 0xbe, 0x39, 0xee, - 0x49, 0x39, 0x1a, 0xdf, 0x40, 0x77, 0x67, 0xee, 0xc3, 0xce, 0xd8, 0x9b, 0x8c, 0xa6, 0x17, 0xcd, - 0xa3, 0x25, 0x19, 0x93, 0xde, 0x93, 0xb2, 0x6a, 0x34, 0x03, 0xdf, 0x3e, 0xc1, 0x01, 0xf8, 0xab, - 0xed, 0x62, 0x21, 0xfe, 0xc3, 0xff, 0x61, 0xb0, 0xbe, 0x5e, 0x6f, 0x17, 0xb3, 0x1b, 0x29, 0x3c, - 0x1c, 0x41, 0x5f, 0xc9, 0x2b, 0x39, 0xbf, 0x95, 0xa2, 0x63, 0xa1, 0x8d, 0x5c, 0x25, 0xa2, 0x8b, - 0x00, 0xc1, 0x76, 0x9d, 0x58, 0xc4, 0x8f, 0x5e, 0xc1, 0xe5, 0xb2, 0x2c, 0x34, 0x97, 0x55, 0x7b, - 0x1c, 0xa3, 0xe8, 0xfb, 0x23, 0x19, 0x8e, 0x3e, 0x41, 0x20, 0x0b, 0xd6, 0x7c, 0xc4, 0x97, 0x30, - 0xcc, 0xca, 0x82, 0xd3, 0x8c, 0xe7, 0xb9, 0xdb, 0xa5, 0xa7, 0x9a, 0x02, 0x86, 0xd0, 0x4f, 0xf3, - 0xbc, 0x22, 0x63, 0xdc, 0xc8, 0x43, 0xf5, 0x74, 0xc5, 0x17, 0x10, 0x68, 0xb3, 0xa1, 0x87, 0xbb, - 0xb0, 0x3b, 0xf6, 0x26, 0x03, 0x55, 0xdf, 0xa2, 0xdf, 0x1d, 0xe8, 0xd7, 0xcb, 0xe0, 0x04, 0x02, - 0x43, 0x45, 0x4e, 0x95, 0x6b, 0x3c, 0x9a, 0x8a, 0x66, 0xdf, 0xd3, 0xd7, 0x55, 0xad, 0x63, 0x0c, - 0xc3, 0x8a, 0x32, 0xbd, 0xd7, 0x54, 0x70, 0x6d, 0xce, 0x39, 0xdc, 0x20, 0x76, 0x6a, 0xd6, 0x3b, - 0x32, 0x9c, 0xee, 0xf6, 0x6e, 0x80, 0xae, 0x6a, 0x0a, 0xf8, 0x1a, 0x40, 0xe7, 0x54, 0xb0, 0xbe, - 0xd3, 0x54, 0x85, 0xfe, 0xd8, 0x9b, 0xf8, 0xaa, 0x55, 0xc1, 0xb7, 0x10, 0x18, 0x4e, 0xf9, 0xd1, - 0x84, 0x3d, 0x17, 0x5e, 0x78, 0x96, 0x43, 0xbc, 0x71, 0xba, 0xaa, 0x39, 0x44, 0xf0, 0x99, 0x7e, - 0x72, 0x18, 0x38, 0x13, 0xdc, 0x39, 0xfa, 0x0c, 0xc1, 0x89, 0x6a, 0xe5, 0x34, 0x84, 0x9e, 0x54, - 0xea, 0x5a, 0x09, 0xcf, 0xa6, 0xf1, 0x71, 0x2b, 0xb7, 0x32, 0x11, 0x1d, 0x1b, 0x98, 0xcd, 0x68, - 0xbe, 0xfa, 0x20, 0xba, 0xf8, 0x0c, 0x86, 0x89, 0x5c, 0xcc, 0x6f, 0xa5, 0x92, 0x89, 0xf0, 0x5d, - 0x6a, 0x2b, 0x25, 0x67, 0x89, 0xe8, 0xd9, 0x46, 0xee, 0x14, 0x44, 0x3f, 0xe0, 0x72, 0x99, 0x56, - 0xdf, 0xda, 0xe1, 0x29, 0x4a, 0xf3, 0x3a, 0x3f, 0xeb, 0x2c, 0x39, 0x53, 0xfe, 0xed, 0xec, 0x49, - 0xc7, 0x18, 0xf0, 0x21, 0x35, 0xac, 0x28, 0x3b, 0xcc, 0x1b, 0x4f, 0x3a, 0xce, 0x93, 0xbf, 0x28, - 0x5f, 0x02, 0xf7, 0xf7, 0xbf, 0xfb, 0x13, 0x00, 0x00, 0xff, 0xff, 0xa0, 0x5b, 0x0f, 0xe6, 0x13, - 0x03, 0x00, 0x00, + // 453 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x74, 0x92, 0x41, 0x8f, 0x93, 0x4c, + 0x18, 0xc7, 0x5f, 0x0a, 0xa5, 0xe5, 0xe9, 0xab, 0x99, 0x7d, 0x0e, 0x86, 0x64, 0xd5, 0x10, 0xbc, + 0x70, 0x22, 0xa6, 0x7a, 0xf2, 0xd6, 0x2c, 0x13, 0xd3, 0xa4, 0xed, 0xd6, 0xe9, 0xb2, 0x17, 0x4f, + 0x08, 0xcf, 0xae, 0x13, 0xb7, 0x80, 0xcc, 0x6c, 0xb5, 0x1f, 0xcb, 0xef, 0xe0, 0x07, 0x33, 0x4c, + 0xd9, 0x40, 0x52, 0xbd, 0x31, 0xf3, 0xff, 0xcd, 0xe4, 0x99, 0xdf, 0x1f, 0xc0, 0xbc, 0x2a, 0x0f, + 0xd4, 0xa8, 0x4c, 0xcb, 0xaa, 0x8c, 0xeb, 0xa6, 0xd2, 0x15, 0x4e, 0x1b, 0x99, 0x57, 0xf9, 0x57, + 0xd2, 0xe1, 0x2f, 0x0b, 0x2e, 0xae, 0x06, 0x00, 0x3f, 0x50, 0xa9, 0xf1, 0x3d, 0x38, 0xfa, 0x58, + 0x93, 0x6f, 0x05, 0x56, 0xf4, 0x7c, 0x1e, 0xc4, 0x4f, 0x78, 0x7c, 0x86, 0xc6, 0x37, 0xc7, 0x9a, + 0x84, 0xa1, 0xf1, 0x0d, 0xd8, 0x7b, 0x75, 0xef, 0x8f, 0x02, 0x2b, 0x9a, 0xcd, 0x2f, 0xfa, 0x43, + 0x6b, 0x52, 0x2a, 0xbb, 0x27, 0xd1, 0xa6, 0xe1, 0x02, 0x9c, 0xf6, 0x08, 0x4e, 0xc1, 0xd9, 0xa4, + 0xab, 0x15, 0xfb, 0x0f, 0xff, 0x87, 0xe9, 0xf6, 0x7a, 0x9b, 0xae, 0x16, 0x37, 0x9c, 0x59, 0x38, + 0x83, 0x89, 0xe0, 0x57, 0x7c, 0x79, 0xcb, 0xd9, 0xa8, 0x85, 0x76, 0x7c, 0x93, 0x30, 0x1b, 0x01, + 0xdc, 0x74, 0x9b, 0xb4, 0x88, 0x13, 0xbe, 0x82, 0xcb, 0x75, 0x55, 0x4a, 0x5d, 0x35, 0xc3, 0x71, + 0x94, 0xa0, 0xef, 0x8f, 0xa4, 0x74, 0xf8, 0x01, 0x5c, 0x5e, 0x6a, 0xa9, 0x8f, 0xe8, 0xc3, 0x24, + 0x2b, 0x8a, 0x86, 0x94, 0x32, 0x43, 0x79, 0xe2, 0x69, 0x89, 0x2f, 0xc0, 0x95, 0x6a, 0x47, 0x0f, + 0x77, 0xbe, 0x1d, 0x58, 0xd1, 0x54, 0x74, 0xab, 0xf0, 0xf7, 0x08, 0x26, 0xdd, 0xb8, 0x18, 0x81, + 0xab, 0xa8, 0x2c, 0xa8, 0x31, 0x1a, 0x66, 0x73, 0xd6, 0xbf, 0xe8, 0x74, 0xbf, 0xe8, 0x72, 0x8c, + 0xc1, 0x6b, 0x28, 0x97, 0xb5, 0xa4, 0x52, 0x77, 0xcf, 0x3f, 0x87, 0x7b, 0x04, 0x5f, 0x82, 0xa7, + 0xe5, 0x9e, 0x94, 0xce, 0xf6, 0xb5, 0x19, 0xc0, 0x16, 0xfd, 0x06, 0xbe, 0x06, 0x90, 0x05, 0x95, + 0x5a, 0xde, 0x49, 0x6a, 0x7c, 0x27, 0xb0, 0x22, 0x47, 0x0c, 0x76, 0xf0, 0x2d, 0xb8, 0x4a, 0x67, + 0xfa, 0x51, 0xf9, 0x63, 0x53, 0x8f, 0x7f, 0x66, 0x3a, 0xde, 0x99, 0x5c, 0x74, 0x1c, 0x22, 0x38, + 0x9a, 0x7e, 0x6a, 0xdf, 0x35, 0x12, 0xcc, 0x77, 0xf8, 0x19, 0xdc, 0x13, 0x35, 0x68, 0xc2, 0x83, + 0x31, 0x17, 0xe2, 0x5a, 0x30, 0xab, 0xf5, 0xfd, 0x29, 0xe5, 0x29, 0x4f, 0xd8, 0xa8, 0xad, 0xa4, + 0x6d, 0x61, 0xb9, 0xf9, 0xc8, 0x6c, 0x7c, 0x06, 0x5e, 0xc2, 0x57, 0xcb, 0x5b, 0x2e, 0x78, 0xc2, + 0x1c, 0xd3, 0xcb, 0x46, 0xf0, 0x45, 0xc2, 0xc6, 0xed, 0x45, 0xe6, 0xcb, 0x0d, 0x7f, 0xc0, 0xe5, + 0x3a, 0x6b, 0xbe, 0x0d, 0xeb, 0x11, 0x94, 0x15, 0x5d, 0x43, 0xad, 0x59, 0x32, 0x52, 0xfe, 0x6d, + 0xf6, 0x94, 0x63, 0x0c, 0xf8, 0x90, 0x29, 0x2d, 0x28, 0x3f, 0x2c, 0x7b, 0x27, 0x23, 0xe3, 0xe4, + 0x2f, 0xc9, 0x17, 0xd7, 0xfc, 0xdf, 0xef, 0xfe, 0x04, 0x00, 0x00, 0xff, 0xff, 0x5c, 0x9e, 0xac, + 0x63, 0xf5, 0x02, 0x00, 0x00, } diff --git a/rpc/conversation.proto b/rpc/conversation.proto index a41f661..52855d4 100644 --- a/rpc/conversation.proto +++ b/rpc/conversation.proto @@ -18,8 +18,7 @@ message MonitorConversationsRequest { } message Entity { - // contactId and address MAY be unspecified for self - int32 contactId = 1; + // address MAY be unspecified for self string address = 2; bool isSelf = 3; }