chore(communities)_: request missing channels' encryption keys in a loop
closes: status-im/status-desktop#14683
This commit is contained in:
parent
5059c19aae
commit
9403475572
|
@ -375,7 +375,7 @@ func (o *Community) MarshalJSON() ([]byte, error) {
|
|||
CategoryID: c.CategoryId,
|
||||
HideIfPermissionsNotMet: c.HideIfPermissionsNotMet,
|
||||
Position: int(c.Position),
|
||||
MissingEncryptionKey: !o.IsMemberInChat(o.MemberIdentity(), id) && o.IsMemberLikelyInChat(id),
|
||||
MissingEncryptionKey: o.HasMissingEncryptionKey(id),
|
||||
}
|
||||
|
||||
if chat.TokenGated {
|
||||
|
@ -771,11 +771,15 @@ func (o *Community) HasMember(pk *ecdsa.PublicKey) bool {
|
|||
return o.hasMember(pk)
|
||||
}
|
||||
|
||||
func (o *Community) isMemberInChat(pk *ecdsa.PublicKey, chatID string) bool {
|
||||
return o.getChatMember(pk, chatID) != nil
|
||||
}
|
||||
|
||||
func (o *Community) IsMemberInChat(pk *ecdsa.PublicKey, chatID string) bool {
|
||||
o.mutex.Lock()
|
||||
defer o.mutex.Unlock()
|
||||
|
||||
return o.getChatMember(pk, chatID) != nil
|
||||
return o.isMemberInChat(pk, chatID)
|
||||
}
|
||||
|
||||
// Uses bloom filter members list to estimate presence in the channel.
|
||||
|
@ -1915,6 +1919,15 @@ func (o *Community) ChannelEncrypted(channelID string) bool {
|
|||
return o.channelEncrypted(channelID)
|
||||
}
|
||||
|
||||
func (o *Community) HasMissingEncryptionKey(channelID string) bool {
|
||||
o.mutex.Lock()
|
||||
defer o.mutex.Unlock()
|
||||
|
||||
return o.channelEncrypted(channelID) &&
|
||||
!o.isMemberInChat(o.MemberIdentity(), channelID) &&
|
||||
o.IsMemberLikelyInChat(channelID)
|
||||
}
|
||||
|
||||
func TokenPermissionsByType(permissions map[string]*CommunityTokenPermission, permissionType protobuf.CommunityTokenPermission_Type) []*CommunityTokenPermission {
|
||||
result := make([]*CommunityTokenPermission, 0)
|
||||
for _, tokenPermission := range permissions {
|
||||
|
|
|
@ -5159,3 +5159,92 @@ func (c *Community) ToStatusLinkPreview() (*common.StatusCommunityLinkPreview, e
|
|||
|
||||
return communityLinkPreview, nil
|
||||
}
|
||||
|
||||
func (m *Manager) determineChannelsForHRKeysRequest(c *Community, now int64) ([]string, error) {
|
||||
result := []string{}
|
||||
|
||||
channelsWithMissingKeys := func() map[string]struct{} {
|
||||
r := map[string]struct{}{}
|
||||
for id := range c.Chats() {
|
||||
if c.HasMissingEncryptionKey(id) {
|
||||
r[id] = struct{}{}
|
||||
}
|
||||
}
|
||||
return r
|
||||
}()
|
||||
|
||||
if len(channelsWithMissingKeys) == 0 {
|
||||
return result, nil
|
||||
}
|
||||
|
||||
requests, err := m.persistence.GetEncryptionKeyRequests(c.ID(), channelsWithMissingKeys)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for channelID := range channelsWithMissingKeys {
|
||||
request, ok := requests[channelID]
|
||||
if !ok {
|
||||
// If there's no prior request, ask for encryption key now
|
||||
result = append(result, channelID)
|
||||
continue
|
||||
}
|
||||
|
||||
// Exponential backoff formula: initial delay * 2^(requestCount - 1)
|
||||
initialDelay := int64(10 * 60 * 1000) // 10 minutes in milliseconds
|
||||
backoffDuration := initialDelay * (1 << (request.requestedCount - 1))
|
||||
nextRequestTime := request.requestedAt + backoffDuration
|
||||
|
||||
if now >= nextRequestTime {
|
||||
result = append(result, channelID)
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
type CommunityWithChannelIDs struct {
|
||||
Community *Community
|
||||
ChannelIDs []string
|
||||
}
|
||||
|
||||
// DetermineChannelsForHRKeysRequest identifies channels in a community that
|
||||
// should ask for encryption keys based on their current state and past request records,
|
||||
// as determined by exponential backoff.
|
||||
func (m *Manager) DetermineChannelsForHRKeysRequest() ([]*CommunityWithChannelIDs, error) {
|
||||
communities, err := m.Joined()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := []*CommunityWithChannelIDs{}
|
||||
now := time.Now().UnixMilli()
|
||||
|
||||
for _, c := range communities {
|
||||
if c.IsControlNode() {
|
||||
continue
|
||||
}
|
||||
|
||||
channelsToRequest, err := m.determineChannelsForHRKeysRequest(c, now)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(channelsToRequest) > 0 {
|
||||
result = append(result, &CommunityWithChannelIDs{
|
||||
Community: c,
|
||||
ChannelIDs: channelsToRequest,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (m *Manager) updateEncryptionKeysRequests(communityID types.HexBytes, channelIDs []string, now int64) error {
|
||||
return m.persistence.UpdateAndPruneEncryptionKeyRequests(communityID, channelIDs, now)
|
||||
}
|
||||
|
||||
func (m *Manager) UpdateEncryptionKeysRequests(communityID types.HexBytes, channelIDs []string) error {
|
||||
return m.updateEncryptionKeysRequests(communityID, channelIDs, time.Now().UnixMilli())
|
||||
}
|
||||
|
|
|
@ -2055,3 +2055,93 @@ func (s *ManagerSuite) TestFillMissingCommunityTokens() {
|
|||
s.Require().NoError(err)
|
||||
s.Require().Len(community.CommunityTokensMetadata(), 1)
|
||||
}
|
||||
|
||||
func (s *ManagerSuite) TestDetermineChannelsForHRKeysRequest() {
|
||||
request := &requests.CreateCommunity{
|
||||
Name: "status",
|
||||
Description: "token membership description",
|
||||
Membership: protobuf.CommunityPermissions_AUTO_ACCEPT,
|
||||
}
|
||||
|
||||
community, err := s.manager.CreateCommunity(request, true)
|
||||
s.Require().NoError(err)
|
||||
s.Require().NotNil(community)
|
||||
|
||||
channel := &protobuf.CommunityChat{
|
||||
Members: map[string]*protobuf.CommunityMember{
|
||||
common.PubkeyToHex(&s.manager.identity.PublicKey): {},
|
||||
},
|
||||
}
|
||||
|
||||
description := community.config.CommunityDescription
|
||||
description.Chats = map[string]*protobuf.CommunityChat{}
|
||||
description.Chats["channel-id"] = channel
|
||||
|
||||
// Simulate channel encrypted
|
||||
_, err = community.UpsertTokenPermission(&protobuf.CommunityTokenPermission{
|
||||
ChatIds: []string{ChatID(community.IDString(), "channel-id")},
|
||||
})
|
||||
s.Require().NoError(err)
|
||||
|
||||
err = generateBloomFiltersForChannels(description, s.manager.identity)
|
||||
s.Require().NoError(err)
|
||||
|
||||
now := int64(1)
|
||||
tenMinutes := int64(10 * 60 * 1000)
|
||||
|
||||
// Member does not have missing encryption keys
|
||||
channels, err := s.manager.determineChannelsForHRKeysRequest(community, now)
|
||||
s.Require().NoError(err)
|
||||
s.Require().Empty(channels)
|
||||
|
||||
// Simulate missing encryption key
|
||||
channel.Members = map[string]*protobuf.CommunityMember{}
|
||||
|
||||
// Channel without prior request should be returned
|
||||
channels, err = s.manager.determineChannelsForHRKeysRequest(community, now)
|
||||
s.Require().NoError(err)
|
||||
s.Require().Len(channels, 1)
|
||||
s.Require().Equal("channel-id", channels[0])
|
||||
|
||||
// Simulate encryption keys request
|
||||
err = s.manager.updateEncryptionKeysRequests(community.ID(), []string{"channel-id"}, now)
|
||||
s.Require().NoError(err)
|
||||
|
||||
// Channel with prior request should not be returned before backoff interval
|
||||
channels, err = s.manager.determineChannelsForHRKeysRequest(community, now)
|
||||
s.Require().NoError(err)
|
||||
s.Require().Len(channels, 0)
|
||||
|
||||
// Channel with prior request should be returned only after backoff interval
|
||||
channels, err = s.manager.determineChannelsForHRKeysRequest(community, now+tenMinutes)
|
||||
s.Require().NoError(err)
|
||||
s.Require().Len(channels, 1)
|
||||
s.Require().Equal("channel-id", channels[0])
|
||||
|
||||
// Simulate multiple encryption keys request
|
||||
err = s.manager.updateEncryptionKeysRequests(community.ID(), []string{"channel-id"}, now+tenMinutes)
|
||||
s.Require().NoError(err)
|
||||
err = s.manager.updateEncryptionKeysRequests(community.ID(), []string{"channel-id"}, now+2*tenMinutes)
|
||||
s.Require().NoError(err)
|
||||
|
||||
// Channel with prior request should not be returned before backoff interval
|
||||
channels, err = s.manager.determineChannelsForHRKeysRequest(community, now+2*tenMinutes)
|
||||
s.Require().NoError(err)
|
||||
s.Require().Len(channels, 0)
|
||||
|
||||
// Channel with prior request should be returned only after backoff interval
|
||||
channels, err = s.manager.determineChannelsForHRKeysRequest(community, now+6*tenMinutes)
|
||||
s.Require().NoError(err)
|
||||
s.Require().Len(channels, 1)
|
||||
s.Require().Equal("channel-id", channels[0])
|
||||
|
||||
// Simulate encryption key being received (it will remove request for given channel)
|
||||
err = s.manager.updateEncryptionKeysRequests(community.ID(), []string{}, now)
|
||||
s.Require().NoError(err)
|
||||
|
||||
// Channel without prior request should be returned
|
||||
channels, err = s.manager.determineChannelsForHRKeysRequest(community, now)
|
||||
s.Require().NoError(err)
|
||||
s.Require().Len(channels, 1)
|
||||
s.Require().Equal("channel-id", channels[0])
|
||||
}
|
||||
|
|
|
@ -72,6 +72,13 @@ type CommunityRecordBundle struct {
|
|||
installationID *string
|
||||
}
|
||||
|
||||
type EncryptionKeysRequestRecord struct {
|
||||
communityID []byte
|
||||
channelID string
|
||||
requestedAt int64
|
||||
requestedCount uint
|
||||
}
|
||||
|
||||
const OR = " OR "
|
||||
const communitiesBaseQuery = `
|
||||
SELECT
|
||||
|
@ -2092,3 +2099,101 @@ func (p *Persistence) GetCommunityRequestsToJoinRevealedAddresses(communityID []
|
|||
|
||||
return accounts, nil
|
||||
}
|
||||
|
||||
func (p *Persistence) GetEncryptionKeyRequests(communityID []byte, channelIDs map[string]struct{}) (map[string]*EncryptionKeysRequestRecord, error) {
|
||||
result := map[string]*EncryptionKeysRequestRecord{}
|
||||
|
||||
query := "SELECT channel_id, requested_at, requested_count FROM community_encryption_keys_requests WHERE community_id = ? AND channel_id IN (?" + strings.Repeat(",?", len(channelIDs)-1) + ")"
|
||||
|
||||
args := make([]interface{}, 0, len(channelIDs)+1)
|
||||
args = append(args, communityID)
|
||||
for channelID := range channelIDs {
|
||||
args = append(args, channelID)
|
||||
}
|
||||
|
||||
rows, err := p.db.Query(query, args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
for rows.Next() {
|
||||
var channelID string
|
||||
var requestedAt int64
|
||||
var requestedCount uint
|
||||
err := rows.Scan(&channelID, &requestedAt, &requestedCount)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result[channelID] = &EncryptionKeysRequestRecord{
|
||||
communityID: communityID,
|
||||
channelID: channelID,
|
||||
requestedAt: requestedAt,
|
||||
requestedCount: requestedCount,
|
||||
}
|
||||
}
|
||||
|
||||
err = rows.Err()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (p *Persistence) UpdateAndPruneEncryptionKeyRequests(communityID types.HexBytes, channelIDs []string, requestedAt int64) error {
|
||||
tx, err := p.db.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if err == nil {
|
||||
err = tx.Commit()
|
||||
return
|
||||
}
|
||||
// don't shadow original error
|
||||
_ = tx.Rollback()
|
||||
}()
|
||||
|
||||
if len(channelIDs) == 0 {
|
||||
deleteQuery := "DELETE FROM community_encryption_keys_requests WHERE community_id = ?"
|
||||
_, err = tx.Exec(deleteQuery, communityID)
|
||||
return err
|
||||
}
|
||||
|
||||
// Delete entries that do not match the channelIDs list
|
||||
deleteQuery := "DELETE FROM community_encryption_keys_requests WHERE community_id = ? AND channel_id NOT IN (?" + strings.Repeat(",?", len(channelIDs)-1) + ")"
|
||||
args := make([]interface{}, 0, len(channelIDs)+1)
|
||||
args = append(args, communityID)
|
||||
for _, channelID := range channelIDs {
|
||||
args = append(args, channelID)
|
||||
}
|
||||
_, err = tx.Exec(deleteQuery, args...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
stmt, err := tx.Prepare(`
|
||||
INSERT INTO community_encryption_keys_requests (community_id, channel_id, requested_at, requested_count)
|
||||
VALUES (?, ?, ?, 1)
|
||||
ON CONFLICT(community_id, channel_id)
|
||||
DO UPDATE SET
|
||||
requested_at = excluded.requested_at,
|
||||
requested_count = community_encryption_keys_requests.requested_count + 1
|
||||
WHERE excluded.requested_at > community_encryption_keys_requests.requested_at
|
||||
`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer stmt.Close()
|
||||
|
||||
for _, channelID := range channelIDs {
|
||||
_, err := stmt.Exec(communityID, channelID, requestedAt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -848,6 +848,7 @@ func (m *Messenger) Start() (*MessengerResponse, error) {
|
|||
}
|
||||
m.startMessageSegmentsCleanupLoop()
|
||||
m.startHashRatchetEncryptedMessagesCleanupLoop()
|
||||
m.startRequestMissingCommunityChannelsHRKeysLoop()
|
||||
|
||||
if err := m.cleanTopics(); err != nil {
|
||||
return nil, err
|
||||
|
|
|
@ -393,25 +393,7 @@ func (m *Messenger) requestCommunityKeysAndSharedAddresses(state *ReceivedMessag
|
|||
}
|
||||
|
||||
if isEncrypted {
|
||||
request := &protobuf.CommunityEncryptionKeysRequest{
|
||||
CommunityId: syncCommunity.Id,
|
||||
}
|
||||
|
||||
payload, err := proto.Marshal(request)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rawMessage := &common.RawMessage{
|
||||
Payload: payload,
|
||||
Sender: m.identity,
|
||||
CommunityID: community.ID(),
|
||||
SkipEncryptionLayer: true,
|
||||
MessageType: protobuf.ApplicationMetadataMessage_COMMUNITY_ENCRYPTION_KEYS_REQUEST,
|
||||
}
|
||||
|
||||
_, err = m.SendMessageToControlNode(community, rawMessage)
|
||||
|
||||
err = m.requestCommunityEncryptionKeys(community, nil)
|
||||
if err != nil {
|
||||
m.logger.Error("failed to request community encryption keys", zap.String("communityId", community.IDString()), zap.Error(err))
|
||||
return err
|
||||
|
|
|
@ -573,7 +573,7 @@ func (m *Messenger) HandleCommunityEncryptionKeysRequest(state *ReceivedMessageS
|
|||
return communities.ErrNotControlNode
|
||||
}
|
||||
signer := state.CurrentMessageState.PublicKey
|
||||
return m.handleCommunityEncryptionKeysRequest(community, signer)
|
||||
return m.handleCommunityEncryptionKeysRequest(community, message.ChatIds, signer)
|
||||
}
|
||||
|
||||
func (m *Messenger) HandleCommunitySharedAddressesRequest(state *ReceivedMessageState, message *protobuf.CommunitySharedAddressesRequest, statusMessage *v1protocol.StatusMessage) error {
|
||||
|
@ -603,7 +603,7 @@ func (m *Messenger) HandleCommunityTokenAction(state *ReceivedMessageState, mess
|
|||
return m.communityTokensService.ProcessCommunityTokenAction(message)
|
||||
}
|
||||
|
||||
func (m *Messenger) handleCommunityEncryptionKeysRequest(community *communities.Community, signer *ecdsa.PublicKey) error {
|
||||
func (m *Messenger) handleCommunityEncryptionKeysRequest(community *communities.Community, channelIDs []string, signer *ecdsa.PublicKey) error {
|
||||
if !community.HasMember(signer) {
|
||||
return communities.ErrMemberNotFound
|
||||
}
|
||||
|
@ -624,7 +624,17 @@ func (m *Messenger) handleCommunityEncryptionKeysRequest(community *communities.
|
|||
}
|
||||
}
|
||||
|
||||
requestedChannelIDs := map[string]bool{}
|
||||
for _, channelID := range channelIDs {
|
||||
requestedChannelIDs[channelID] = true
|
||||
}
|
||||
|
||||
for channelID, channel := range community.Chats() {
|
||||
// Skip channels that weren't requested
|
||||
if len(requestedChannelIDs) > 0 && !requestedChannelIDs[channelID] {
|
||||
continue
|
||||
}
|
||||
|
||||
channelMembers := channel.GetMembers()
|
||||
member, exists := channelMembers[pkStr]
|
||||
if exists && community.ChannelEncrypted(channelID) {
|
||||
|
@ -5018,3 +5028,69 @@ func (m *Messenger) shareRevealedAccountsOnSoftKick(community *communities.Commu
|
|||
messengerResponse.AddRequestToJoinCommunity(requestToJoin)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Messenger) requestCommunityEncryptionKeys(community *communities.Community, channelIDs []string) error {
|
||||
m.logger.Debug("request community encryption keys",
|
||||
zap.String("communityID", community.IDString()),
|
||||
zap.Strings("channels", channelIDs))
|
||||
|
||||
request := &protobuf.CommunityEncryptionKeysRequest{
|
||||
CommunityId: community.ID(),
|
||||
ChatIds: channelIDs,
|
||||
}
|
||||
|
||||
payload, err := proto.Marshal(request)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rawMessage := &common.RawMessage{
|
||||
Payload: payload,
|
||||
Sender: m.identity,
|
||||
CommunityID: community.ID(),
|
||||
SkipEncryptionLayer: true,
|
||||
MessageType: protobuf.ApplicationMetadataMessage_COMMUNITY_ENCRYPTION_KEYS_REQUEST,
|
||||
}
|
||||
|
||||
_, err = m.SendMessageToControlNode(community, rawMessage)
|
||||
return err
|
||||
}
|
||||
|
||||
func (m *Messenger) startRequestMissingCommunityChannelsHRKeysLoop() {
|
||||
logger := m.logger.Named("requestMissingCommunityChannelsHRKeysLoop")
|
||||
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case <-time.After(5 * time.Minute):
|
||||
communitiesChannels, err := m.communitiesManager.DetermineChannelsForHRKeysRequest()
|
||||
if err != nil {
|
||||
logger.Error("failed to determine channels for encryption keys request", zap.Error(err))
|
||||
continue
|
||||
}
|
||||
|
||||
for _, cc := range communitiesChannels {
|
||||
err := m.requestCommunityEncryptionKeys(cc.Community, cc.ChannelIDs)
|
||||
if err != nil {
|
||||
logger.Error("failed to request channels' encryption keys",
|
||||
zap.String("communityID", cc.Community.IDString()),
|
||||
zap.Strings("channelIDs", cc.ChannelIDs),
|
||||
zap.Error(err))
|
||||
continue
|
||||
}
|
||||
|
||||
err = m.communitiesManager.UpdateEncryptionKeysRequests(cc.Community.ID(), cc.ChannelIDs)
|
||||
if err != nil {
|
||||
logger.Error("failed to update channels' encryption keys requests",
|
||||
zap.String("communityID", cc.Community.IDString()),
|
||||
zap.Strings("channelIDs", cc.ChannelIDs),
|
||||
zap.Error(err))
|
||||
}
|
||||
}
|
||||
|
||||
case <-m.quit:
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
|
|
@ -141,6 +141,7 @@
|
|||
// 1716413241_remove_social_links.up.sql (38B)
|
||||
// 1716891408_add_community_token_transaction_hash.up.sql (65B)
|
||||
// 1719906191_add_community_token_version.up.sql (65B)
|
||||
// 1720636181_add_community_encryption_keys_requests.up.sql (236B)
|
||||
// README.md (554B)
|
||||
// doc.go (870B)
|
||||
|
||||
|
@ -3030,6 +3031,26 @@ func _1719906191_add_community_token_versionUpSql() (*asset, error) {
|
|||
return a, nil
|
||||
}
|
||||
|
||||
var __1720636181_add_community_encryption_keys_requestsUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x74\x8e\xc1\x0a\x82\x40\x10\x86\xef\x3e\xc5\x7f\x54\xf0\x0d\x3a\x69\x4c\xb1\xb4\x69\xac\x13\xe8\x69\x11\x5d\x48\xca\xb5\x74\x3d\xf8\xf6\x51\x06\x2d\x41\xd7\xf9\xbe\xf9\x66\xb6\x8a\x12\x26\x70\x92\x4a\x82\xd8\x21\xcb\x19\x54\x8a\x82\x0b\x34\x43\xdf\xcf\xb6\x73\x8b\x36\xb6\x19\x97\xbb\xeb\x06\xab\xaf\x66\x99\xf4\x68\x1e\xb3\x99\xdc\x84\x30\x00\xe0\x89\x5d\x8b\x54\xe6\xe9\xbb\x92\x9d\xa5\x8c\x57\x7e\xa9\xad\x35\xb7\x17\x65\x2a\x79\x1d\x7e\x1a\xa6\xd5\xb5\x83\xc8\x98\xf6\xa4\x7e\xf6\xbe\x4a\x33\xcc\xf6\x9f\x75\x52\xe2\x98\xa8\x0a\x07\xaa\x10\xfa\xaf\xc4\xde\xe1\x28\x88\x36\xc1\x33\x00\x00\xff\xff\xbd\x64\xf2\x7d\xec\x00\x00\x00")
|
||||
|
||||
func _1720636181_add_community_encryption_keys_requestsUpSqlBytes() ([]byte, error) {
|
||||
return bindataRead(
|
||||
__1720636181_add_community_encryption_keys_requestsUpSql,
|
||||
"1720636181_add_community_encryption_keys_requests.up.sql",
|
||||
)
|
||||
}
|
||||
|
||||
func _1720636181_add_community_encryption_keys_requestsUpSql() (*asset, error) {
|
||||
bytes, err := _1720636181_add_community_encryption_keys_requestsUpSqlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1720636181_add_community_encryption_keys_requests.up.sql", size: 236, mode: os.FileMode(0644), modTime: time.Unix(1700000000, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xd3, 0x9c, 0x7c, 0xb6, 0x53, 0x6f, 0xe, 0xc3, 0xff, 0xd5, 0x82, 0xc9, 0x21, 0xd6, 0x51, 0x20, 0xeb, 0x29, 0x75, 0xb5, 0x90, 0x35, 0x6d, 0x28, 0xd6, 0xe9, 0x1d, 0x9c, 0x8b, 0x86, 0xdc, 0x68}}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
var _readmeMd = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x54\x91\xc1\xce\xd3\x30\x10\x84\xef\x7e\x8a\x91\x7a\x01\xa9\x2a\x8f\xc0\x0d\x71\x82\x03\x48\x1c\xc9\x36\x9e\x36\x96\x1c\x6f\xf0\xae\x93\xe6\xed\x91\xa3\xc2\xdf\xff\x66\xed\xd8\x33\xdf\x78\x4f\xa7\x13\xbe\xea\x06\x57\x6c\x35\x39\x31\xa7\x7b\x15\x4f\x5a\xec\x73\x08\xbf\x08\x2d\x79\x7f\x4a\x43\x5b\x86\x17\xfd\x8c\x21\xea\x56\x5e\x47\x90\x4a\x14\x75\x48\xde\x64\x37\x2c\x6a\x96\xae\x99\x48\x05\xf6\x27\x77\x13\xad\x08\xae\x8a\x51\xe7\x25\xf3\xf1\xa9\x9f\xf9\x58\x58\x2c\xad\xbc\xe0\x8b\x56\xf0\x21\x5d\xeb\x4c\x95\xb3\xae\x84\x60\xd4\xdc\xe6\x82\x5d\x1b\x36\x6d\x39\x62\x92\xf5\xb8\x11\xdb\x92\xd3\x28\xce\xe0\x13\xe1\x72\xcd\x3c\x63\xd4\x65\x87\xae\xac\xe8\xc3\x28\x2e\x67\x44\x66\x3a\x21\x25\xa2\x72\xac\x14\x67\xbc\x84\x9f\x53\x32\x8c\x52\x70\x25\x56\xd6\xfd\x8d\x05\x37\xad\x30\x9d\x9f\xa6\x86\x0f\xcd\x58\x7f\xcf\x34\x93\x3b\xed\x90\x9f\xa4\x1f\xcf\x30\x85\x4d\x07\x58\xaf\x7f\x25\xc4\x9d\xf3\x72\x64\x84\xd0\x7f\xf9\x9b\x3a\x2d\x84\xef\x85\x48\x66\x8d\xd8\x88\x9b\x8c\x8c\x98\x5b\xf6\x74\x14\x4e\x33\x0d\xc9\xe0\x93\x38\xda\x12\xc5\x69\xbd\xe4\xf0\x2e\x7a\x78\x07\x1c\xfe\x13\x9f\x91\x29\x31\x95\x7b\x7f\x62\x59\x37\xb4\xe5\x5e\x25\xfe\x33\xee\xd5\x53\x71\xd6\xda\x3a\xd8\xcb\xde\x2e\xf8\xa1\x90\x55\x53\x0c\xc7\xaa\x0d\xe9\x76\x14\x29\x1c\x7b\x68\xdd\x2f\xe1\x6f\x00\x00\x00\xff\xff\x3c\x0a\xc2\xfe\x2a\x02\x00\x00")
|
||||
|
||||
func readmeMdBytes() ([]byte, error) {
|
||||
|
@ -3302,6 +3323,7 @@ var _bindata = map[string]func() (*asset, error){
|
|||
"1716413241_remove_social_links.up.sql": _1716413241_remove_social_linksUpSql,
|
||||
"1716891408_add_community_token_transaction_hash.up.sql": _1716891408_add_community_token_transaction_hashUpSql,
|
||||
"1719906191_add_community_token_version.up.sql": _1719906191_add_community_token_versionUpSql,
|
||||
"1720636181_add_community_encryption_keys_requests.up.sql": _1720636181_add_community_encryption_keys_requestsUpSql,
|
||||
"README.md": readmeMd,
|
||||
"doc.go": docGo,
|
||||
}
|
||||
|
@ -3493,6 +3515,7 @@ var _bintree = &bintree{nil, map[string]*bintree{
|
|||
"1716413241_remove_social_links.up.sql": {_1716413241_remove_social_linksUpSql, map[string]*bintree{}},
|
||||
"1716891408_add_community_token_transaction_hash.up.sql": {_1716891408_add_community_token_transaction_hashUpSql, map[string]*bintree{}},
|
||||
"1719906191_add_community_token_version.up.sql": {_1719906191_add_community_token_versionUpSql, map[string]*bintree{}},
|
||||
"1720636181_add_community_encryption_keys_requests.up.sql": {_1720636181_add_community_encryption_keys_requestsUpSql, map[string]*bintree{}},
|
||||
"README.md": {readmeMd, map[string]*bintree{}},
|
||||
"doc.go": {docGo, map[string]*bintree{}},
|
||||
}}
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
CREATE TABLE IF NOT EXISTS community_encryption_keys_requests (
|
||||
community_id BLOB NOT NULL,
|
||||
channel_id TEXT,
|
||||
requested_at INTEGER NOT NULL,
|
||||
requested_count INTEGER NOT NULL,
|
||||
PRIMARY KEY (community_id, channel_id)
|
||||
);
|
|
@ -2799,7 +2799,8 @@ type CommunityEncryptionKeysRequest struct {
|
|||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
CommunityId []byte `protobuf:"bytes,1,opt,name=community_id,json=communityId,proto3" json:"community_id,omitempty"`
|
||||
CommunityId []byte `protobuf:"bytes,1,opt,name=community_id,json=communityId,proto3" json:"community_id,omitempty"`
|
||||
ChatIds []string `protobuf:"bytes,2,rep,name=chat_ids,json=chatIds,proto3" json:"chat_ids,omitempty"`
|
||||
}
|
||||
|
||||
func (x *CommunityEncryptionKeysRequest) Reset() {
|
||||
|
@ -2841,6 +2842,13 @@ func (x *CommunityEncryptionKeysRequest) GetCommunityId() []byte {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (x *CommunityEncryptionKeysRequest) GetChatIds() []string {
|
||||
if x != nil {
|
||||
return x.ChatIds
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type CommunitySharedAddressesRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
|
@ -3467,26 +3475,27 @@ var file_communities_proto_rawDesc = []byte{
|
|||
0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x0d, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
|
||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38,
|
||||
0x01, 0x22, 0x43, 0x0a, 0x1e, 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x45, 0x6e,
|
||||
0x01, 0x22, 0x5e, 0x0a, 0x1e, 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x45, 0x6e,
|
||||
0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79,
|
||||
0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6d, 0x6d, 0x75,
|
||||
0x6e, 0x69, 0x74, 0x79, 0x49, 0x64, 0x22, 0x44, 0x0a, 0x1f, 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e,
|
||||
0x69, 0x74, 0x79, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73,
|
||||
0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6d,
|
||||
0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52,
|
||||
0x0b, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x49, 0x64, 0x22, 0x8d, 0x01, 0x0a,
|
||||
0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64,
|
||||
0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x5f, 0x69,
|
||||
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69,
|
||||
0x74, 0x79, 0x49, 0x64, 0x12, 0x46, 0x0a, 0x11, 0x72, 0x65, 0x76, 0x65, 0x61, 0x6c, 0x65, 0x64,
|
||||
0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32,
|
||||
0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x52, 0x65, 0x76, 0x65, 0x61,
|
||||
0x6c, 0x65, 0x64, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x10, 0x72, 0x65, 0x76, 0x65,
|
||||
0x61, 0x6c, 0x65, 0x64, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x42, 0x0d, 0x5a, 0x0b,
|
||||
0x2e, 0x2f, 0x3b, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x62, 0x06, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x33,
|
||||
0x6e, 0x69, 0x74, 0x79, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x74, 0x5f, 0x69,
|
||||
0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x63, 0x68, 0x61, 0x74, 0x49, 0x64,
|
||||
0x73, 0x22, 0x44, 0x0a, 0x1f, 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x53, 0x68,
|
||||
0x61, 0x72, 0x65, 0x64, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74,
|
||||
0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6d, 0x6d,
|
||||
0x75, 0x6e, 0x69, 0x74, 0x79, 0x49, 0x64, 0x22, 0x8d, 0x01, 0x0a, 0x20, 0x43, 0x6f, 0x6d, 0x6d,
|
||||
0x75, 0x6e, 0x69, 0x74, 0x79, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0x41, 0x64, 0x64, 0x72, 0x65,
|
||||
0x73, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x0c,
|
||||
0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x49, 0x64, 0x12,
|
||||
0x46, 0x0a, 0x11, 0x72, 0x65, 0x76, 0x65, 0x61, 0x6c, 0x65, 0x64, 0x5f, 0x61, 0x63, 0x63, 0x6f,
|
||||
0x75, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x52, 0x65, 0x76, 0x65, 0x61, 0x6c, 0x65, 0x64, 0x41, 0x63,
|
||||
0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x10, 0x72, 0x65, 0x76, 0x65, 0x61, 0x6c, 0x65, 0x64, 0x41,
|
||||
0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x42, 0x0d, 0x5a, 0x0b, 0x2e, 0x2f, 0x3b, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
|
|
|
@ -303,6 +303,7 @@ message CommunityUpdateGrant {
|
|||
|
||||
message CommunityEncryptionKeysRequest {
|
||||
bytes community_id = 1;
|
||||
repeated string chat_ids = 2;
|
||||
}
|
||||
|
||||
message CommunitySharedAddressesRequest {
|
||||
|
|
Loading…
Reference in New Issue