Support delete_history flag in messages.discardEncryption.

This commit is contained in:
levlam 2021-01-18 15:04:31 +03:00
parent a2c1a695d2
commit cc8c0cbe64
7 changed files with 46 additions and 35 deletions

View File

@ -140,7 +140,7 @@ void SecretChatActor::on_result_resendable(NetQueryPtr net_query, Promise<NetQue
} }
void SecretChatActor::replay_close_chat(unique_ptr<log_event::CloseSecretChat> event) { void SecretChatActor::replay_close_chat(unique_ptr<log_event::CloseSecretChat> event) {
do_close_chat_impl(std::move(event)); do_close_chat_impl(event->delete_history, event->log_event_id());
} }
void SecretChatActor::replay_create_chat(unique_ptr<log_event::CreateSecretChat> event) { void SecretChatActor::replay_create_chat(unique_ptr<log_event::CreateSecretChat> event) {
@ -709,10 +709,10 @@ void SecretChatActor::check_status(Status status) {
void SecretChatActor::on_fatal_error(Status status) { void SecretChatActor::on_fatal_error(Status status) {
LOG(ERROR) << "Fatal error: " << status; LOG(ERROR) << "Fatal error: " << status;
cancel_chat(Promise<>()); cancel_chat(false, Promise<>());
} }
void SecretChatActor::cancel_chat(Promise<> promise) { void SecretChatActor::cancel_chat(bool delete_history, Promise<> promise) {
if (close_flag_) { if (close_flag_) {
promise.set_value(Unit()); promise.set_value(Unit());
return; return;
@ -735,26 +735,26 @@ void SecretChatActor::cancel_chat(Promise<> promise) {
auto event = make_unique<log_event::CloseSecretChat>(); auto event = make_unique<log_event::CloseSecretChat>();
event->chat_id = auth_state_.id; event->chat_id = auth_state_.id;
event->set_log_event_id(binlog_add(context_->binlog(), LogEvent::HandlerType::SecretChats, create_storer(*event))); auto log_event_id = binlog_add(context_->binlog(), LogEvent::HandlerType::SecretChats, create_storer(*event));
auto on_sync = PromiseCreator::lambda( auto on_sync = PromiseCreator::lambda([actor_id = actor_id(this), delete_history, log_event_id,
[actor_id = actor_id(this), event = std::move(event), promise = std::move(promise)](Result<Unit> result) mutable { promise = std::move(promise)](Result<Unit> result) mutable {
if (result.is_ok()) { if (result.is_ok()) {
send_closure(actor_id, &SecretChatActor::do_close_chat_impl, std::move(event)); send_closure(actor_id, &SecretChatActor::do_close_chat_impl, delete_history, log_event_id);
promise.set_value(Unit()); promise.set_value(Unit());
} else { } else {
promise.set_error(result.error().clone()); promise.set_error(result.error().clone());
send_closure(actor_id, &SecretChatActor::on_promise_error, result.move_as_error(), "do_close_chat_impl"); send_closure(actor_id, &SecretChatActor::on_promise_error, result.move_as_error(), "cancel_chat");
} }
}); });
context_->binlog()->force_sync(std::move(on_sync)); context_->binlog()->force_sync(std::move(on_sync));
yield(); yield();
} }
void SecretChatActor::do_close_chat_impl(unique_ptr<log_event::CloseSecretChat> event) { void SecretChatActor::do_close_chat_impl(bool delete_history, uint64 log_event_id) {
close_flag_ = true; close_flag_ = true;
close_log_event_id_ = event->log_event_id(); close_log_event_id_ = log_event_id;
LOG(INFO) << "Send messages.discardEncryption"; LOG(INFO) << "Send messages.discardEncryption";
auth_state_.state = State::Closed; auth_state_.state = State::Closed;
context_->secret_chat_db()->set_value(auth_state_); context_->secret_chat_db()->set_value(auth_state_);
@ -762,7 +762,11 @@ void SecretChatActor::do_close_chat_impl(unique_ptr<log_event::CloseSecretChat>
context_->secret_chat_db()->erase_value(pfs_state_); context_->secret_chat_db()->erase_value(pfs_state_);
context_->secret_chat_db()->erase_value(seq_no_state_); context_->secret_chat_db()->erase_value(seq_no_state_);
int32 flags = 0; int32 flags = 0;
auto query = create_net_query(QueryType::DiscardEncryption, telegram_api::messages_discardEncryption(flags, false /*ignored*/, auth_state_.id)); if (delete_history) {
flags |= telegram_api::messages_discardEncryption::DELETE_HISTORY_MASK;
}
auto query = create_net_query(QueryType::DiscardEncryption,
telegram_api::messages_discardEncryption(flags, false /*ignored*/, auth_state_.id));
send_update_secret_chat(); send_update_secret_chat();

View File

@ -112,10 +112,11 @@ class SecretChatActor : public NetQueryCallback {
SecretChatActor(int32 id, unique_ptr<Context> context, bool can_be_empty); SecretChatActor(int32 id, unique_ptr<Context> context, bool can_be_empty);
// First query to new chat must be on of these two // First query to new chat must be one of these two
void update_chat(telegram_api::object_ptr<telegram_api::EncryptedChat> chat); void update_chat(telegram_api::object_ptr<telegram_api::EncryptedChat> chat);
void create_chat(int32 user_id, int64 user_access_hash, int32 random_id, Promise<SecretChatId> promise); void create_chat(int32 user_id, int64 user_access_hash, int32 random_id, Promise<SecretChatId> promise);
void cancel_chat(Promise<> promise);
void cancel_chat(bool delete_history, Promise<> promise);
// Inbound messages // Inbound messages
// Logevent is created by SecretChatsManager, because it must contain qts // Logevent is created by SecretChatsManager, because it must contain qts
@ -637,7 +638,7 @@ class SecretChatActor : public NetQueryCallback {
// DiscardEncryption // DiscardEncryption
void on_fatal_error(Status status); void on_fatal_error(Status status);
void do_close_chat_impl(unique_ptr<log_event::CloseSecretChat> event); void do_close_chat_impl(bool delete_history, uint64 log_event_id);
void on_discard_encryption_result(NetQueryPtr result); void on_discard_encryption_result(NetQueryPtr result);
// Other // Other

View File

@ -106,10 +106,10 @@ void SecretChatsManager::create_chat(int32 user_id, int64 user_access_hash, Prom
send_closure(actor, &SecretChatActor::create_chat, user_id, user_access_hash, random_id, std::move(promise)); send_closure(actor, &SecretChatActor::create_chat, user_id, user_access_hash, random_id, std::move(promise));
} }
void SecretChatsManager::cancel_chat(SecretChatId secret_chat_id, Promise<> promise) { void SecretChatsManager::cancel_chat(SecretChatId secret_chat_id, bool delete_history, Promise<> promise) {
auto actor = get_chat_actor(secret_chat_id.get()); auto actor = get_chat_actor(secret_chat_id.get());
auto safe_promise = SafePromise<>(std::move(promise), Unit()); auto safe_promise = SafePromise<>(std::move(promise), Unit());
send_closure(actor, &SecretChatActor::cancel_chat, std::move(safe_promise)); send_closure(actor, &SecretChatActor::cancel_chat, delete_history, std::move(safe_promise));
} }
void SecretChatsManager::send_message(SecretChatId secret_chat_id, tl_object_ptr<secret_api::decryptedMessage> message, void SecretChatsManager::send_message(SecretChatId secret_chat_id, tl_object_ptr<secret_api::decryptedMessage> message,
@ -235,8 +235,9 @@ void SecretChatsManager::replay_binlog_event(BinlogEvent &&binlog_event) {
case log_event::SecretChatEvent::Type::CreateSecretChat: case log_event::SecretChatEvent::Type::CreateSecretChat:
return replay_create_chat( return replay_create_chat(
unique_ptr<log_event::CreateSecretChat>(static_cast<log_event::CreateSecretChat *>(message.release()))); unique_ptr<log_event::CreateSecretChat>(static_cast<log_event::CreateSecretChat *>(message.release())));
default:
LOG(FATAL) << "Unknown log event type " << tag("type", format::as_hex(static_cast<int32>(message->get_type())));
} }
LOG(FATAL) << "Unknown log event type " << tag("type", format::as_hex(static_cast<int32>(message->get_type())));
} }
void SecretChatsManager::binlog_replay_finish() { void SecretChatsManager::binlog_replay_finish() {

View File

@ -30,13 +30,12 @@ class SecretChatsManager : public Actor {
public: public:
explicit SecretChatsManager(ActorShared<> parent); explicit SecretChatsManager(ActorShared<> parent);
// Proxy query to corrensponding SecretChatActor. // Proxy query to corrensponding SecretChatActor
// Look for more info in SecretChatActor.h
void on_update_chat(tl_object_ptr<telegram_api::updateEncryption> update); void on_update_chat(tl_object_ptr<telegram_api::updateEncryption> update);
void on_new_message(tl_object_ptr<telegram_api::EncryptedMessage> &&message_ptr, Promise<Unit> &&promise); void on_new_message(tl_object_ptr<telegram_api::EncryptedMessage> &&message_ptr, Promise<Unit> &&promise);
void create_chat(int32 user_id, int64 user_access_hash, Promise<SecretChatId> promise); void create_chat(int32 user_id, int64 user_access_hash, Promise<SecretChatId> promise);
void cancel_chat(SecretChatId, Promise<> promise); void cancel_chat(SecretChatId secret_chat_id, bool delete_history, Promise<> promise);
void send_message(SecretChatId secret_chat_id, tl_object_ptr<secret_api::decryptedMessage> message, void send_message(SecretChatId secret_chat_id, tl_object_ptr<secret_api::decryptedMessage> message,
tl_object_ptr<telegram_api::InputEncryptedFile> file, Promise<> promise); tl_object_ptr<telegram_api::InputEncryptedFile> file, Promise<> promise);
void send_message_action(SecretChatId secret_chat_id, tl_object_ptr<secret_api::SendMessageAction> action); void send_message_action(SecretChatId secret_chat_id, tl_object_ptr<secret_api::SendMessageAction> action);

View File

@ -6676,7 +6676,7 @@ void Td::on_request(uint64 id, const td_api::deleteSupergroup &request) {
void Td::on_request(uint64 id, td_api::closeSecretChat &request) { void Td::on_request(uint64 id, td_api::closeSecretChat &request) {
CREATE_OK_REQUEST_PROMISE(); CREATE_OK_REQUEST_PROMISE();
send_closure(secret_chats_manager_, &SecretChatsManager::cancel_chat, SecretChatId(request.secret_chat_id_), send_closure(secret_chats_manager_, &SecretChatsManager::cancel_chat, SecretChatId(request.secret_chat_id_), false,
std::move(promise)); std::move(promise));
} }

View File

@ -1643,7 +1643,7 @@ void UpdatesManager::add_pending_qts_update(tl_object_ptr<telegram_api::Update>
int32 old_qts = get_qts(); int32 old_qts = get_qts();
LOG(INFO) << "Process update with qts = " << qts << ", current qts = " << old_qts; LOG(INFO) << "Process update with qts = " << qts << ", current qts = " << old_qts;
if (qts < old_qts - 1000001) { if (qts < old_qts - 10001) {
LOG(WARNING) << "Restore qts after qts overflow from " << old_qts << " to " << qts << " by " LOG(WARNING) << "Restore qts after qts overflow from " << old_qts << " to " << qts << " by "
<< oneline(to_string(update)); << oneline(to_string(update));
add_qts(qts - 1).set_value(Unit()); add_qts(qts - 1).set_value(Unit());

View File

@ -34,12 +34,8 @@ class SecretChatEvent : public LogEventBase<SecretChatEvent> {
virtual Type get_type() const = 0; virtual Type get_type() const = 0;
static constexpr LogEvent::HandlerType get_handler_type() {
return LogEvent::HandlerType::SecretChats;
}
static constexpr int32 version() { static constexpr int32 version() {
return 2; return 3;
} }
template <class F> template <class F>
@ -354,7 +350,7 @@ class OutboundSecretMessage : public SecretChatLogEventBase<OutboundSecretMessag
store(my_out_seq_no, storer); store(my_out_seq_no, storer);
store(his_in_seq_no, storer); store(his_in_seq_no, storer);
bool has_action = static_cast<bool>(action); bool has_action = action != nullptr;
BEGIN_STORE_FLAGS(); BEGIN_STORE_FLAGS();
STORE_FLAG(is_sent); STORE_FLAG(is_sent);
STORE_FLAG(need_notify_user); STORE_FLAG(need_notify_user);
@ -414,21 +410,31 @@ class CloseSecretChat : public SecretChatLogEventBase<CloseSecretChat> {
public: public:
static constexpr Type type = SecretChatEvent::Type::CloseSecretChat; static constexpr Type type = SecretChatEvent::Type::CloseSecretChat;
int32 chat_id = 0; int32 chat_id = 0;
bool delete_history = false;
template <class StorerT> template <class StorerT>
void store(StorerT &storer) const { void store(StorerT &storer) const {
using td::store; using td::store;
BEGIN_STORE_FLAGS();
STORE_FLAG(delete_history);
END_STORE_FLAGS();
store(chat_id, storer); store(chat_id, storer);
} }
template <class ParserT> template <class ParserT>
void parse(ParserT &parser) { void parse(ParserT &parser) {
using td::parse; using td::parse;
if (parser.version() >= 3) {
BEGIN_PARSE_FLAGS();
PARSE_FLAG(delete_history);
END_PARSE_FLAGS();
}
parse(chat_id, parser); parse(chat_id, parser);
} }
StringBuilder &print(StringBuilder &sb) const override { StringBuilder &print(StringBuilder &sb) const override {
return sb << "[Logevent CloseSecretChat " << tag("id", log_event_id()) << tag("chat_id", chat_id) << "]"; return sb << "[Logevent CloseSecretChat " << tag("id", log_event_id()) << tag("chat_id", chat_id)
<< tag("delete_history", delete_history) << "]";
} }
}; };