channels: give kicked/banned/promoted/transferred users a real qts so their client applies it
updateChannelParticipant carries the account's qts per the MTProto spec, but the server always sent Qts: 0, so real clients silently discarded it as a stale duplicate -- the banned/kicked user's channel never vanished locally and no correct "removed by admin" message showed, even though the update was delivered successfully at the transport layer. Add a durable per-device qts queue (channel_participant_event_queue) sharing its qts number space with the existing secret-chat queue (one qts sequence per device, per spec), and use it to stamp a correct, monotonically increasing qts on the update for every device of the affected user -- for channel bans/kicks, admin promotion/demotion, and ownership transfer. A device offline when it happened can now recover the event via updates.getDifference instead of missing it permanently.
This commit is contained in:
parent
97711c9d2e
commit
206bde18e0
16 changed files with 482 additions and 42 deletions
|
|
@ -59,3 +59,20 @@ type EncryptedQueueStore interface {
|
|||
// GetEncryptedFile 按 id + access_hash 回查文件快照(inputEncryptedFile 复用路径)。
|
||||
GetEncryptedFile(ctx context.Context, id, accessHash int64) (domain.EncryptedFileRef, bool, error)
|
||||
}
|
||||
|
||||
// ChannelParticipantQueueStore 持久化 channel 成员关系自通知(kick/ban/promote/
|
||||
// transfer)的设备级 qts 投递队列。updateChannelParticipant 走 qts 序列(MTProto
|
||||
// 规范),与 EncryptedQueueStore 共用同一张 secret_qts_watermarks 水位表——每设备
|
||||
// 只有一条 qts 序列,两类事件按 qts 交错,通过各自独立的表分别落盘,读侧
|
||||
// (updates.getDifference)按 qts 归并成连续序列。
|
||||
type ChannelParticipantQueueStore interface {
|
||||
// AppendChannelParticipantEvent 为接收设备分配下一个 qts 并写入队列,与
|
||||
// reserved_qts 推进同事务(与 AppendEncryptedMessage 共用同一水位表)。
|
||||
AppendChannelParticipantEvent(ctx context.Context, ev domain.DeviceChannelParticipantEvent) (domain.DeviceChannelParticipantEvent, error)
|
||||
// ListChannelParticipantEventsSince 返回接收设备 qts > sinceQts 的连续事件
|
||||
// (qts 升序,最多 limit)。
|
||||
ListChannelParticipantEventsSince(ctx context.Context, receiverAuthKeyID int64, sinceQts, limit int) ([]domain.DeviceChannelParticipantEvent, error)
|
||||
// AckChannelParticipantEvents 标记 qts<=maxQts 行为 acked(confirmed_qts 由
|
||||
// AckEncryptedMessages 在同一张水位表上推进,这里只做本表的 GC 标记)。
|
||||
AckChannelParticipantEvents(ctx context.Context, receiverAuthKeyID int64, maxQts int) error
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue