From cc8c0cbe64c48db41bf340e53313486e99d41784 Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 18 Jan 2021 15:04:31 +0300 Subject: [PATCH] Support delete_history flag in messages.discardEncryption. --- td/telegram/SecretChatActor.cpp | 38 ++++++++++++++------------ td/telegram/SecretChatActor.h | 7 +++-- td/telegram/SecretChatsManager.cpp | 7 +++-- td/telegram/SecretChatsManager.h | 5 ++-- td/telegram/Td.cpp | 2 +- td/telegram/UpdatesManager.cpp | 2 +- td/telegram/logevent/SecretChatEvent.h | 20 +++++++++----- 7 files changed, 46 insertions(+), 35 deletions(-) diff --git a/td/telegram/SecretChatActor.cpp b/td/telegram/SecretChatActor.cpp index f3c6d3512..13ffbf93f 100644 --- a/td/telegram/SecretChatActor.cpp +++ b/td/telegram/SecretChatActor.cpp @@ -140,7 +140,7 @@ void SecretChatActor::on_result_resendable(NetQueryPtr net_query, Promise 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 event) { @@ -709,10 +709,10 @@ void SecretChatActor::check_status(Status status) { void SecretChatActor::on_fatal_error(Status 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_) { promise.set_value(Unit()); return; @@ -735,26 +735,26 @@ void SecretChatActor::cancel_chat(Promise<> promise) { auto event = make_unique(); 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( - [actor_id = actor_id(this), event = std::move(event), promise = std::move(promise)](Result result) mutable { - if (result.is_ok()) { - send_closure(actor_id, &SecretChatActor::do_close_chat_impl, std::move(event)); - promise.set_value(Unit()); - } else { - promise.set_error(result.error().clone()); - send_closure(actor_id, &SecretChatActor::on_promise_error, result.move_as_error(), "do_close_chat_impl"); - } - }); + auto on_sync = PromiseCreator::lambda([actor_id = actor_id(this), delete_history, log_event_id, + promise = std::move(promise)](Result result) mutable { + if (result.is_ok()) { + send_closure(actor_id, &SecretChatActor::do_close_chat_impl, delete_history, log_event_id); + promise.set_value(Unit()); + } else { + promise.set_error(result.error().clone()); + send_closure(actor_id, &SecretChatActor::on_promise_error, result.move_as_error(), "cancel_chat"); + } + }); context_->binlog()->force_sync(std::move(on_sync)); yield(); } -void SecretChatActor::do_close_chat_impl(unique_ptr event) { +void SecretChatActor::do_close_chat_impl(bool delete_history, uint64 log_event_id) { close_flag_ = true; - close_log_event_id_ = event->log_event_id(); + close_log_event_id_ = log_event_id; LOG(INFO) << "Send messages.discardEncryption"; auth_state_.state = State::Closed; context_->secret_chat_db()->set_value(auth_state_); @@ -762,7 +762,11 @@ void SecretChatActor::do_close_chat_impl(unique_ptr context_->secret_chat_db()->erase_value(pfs_state_); context_->secret_chat_db()->erase_value(seq_no_state_); 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(); diff --git a/td/telegram/SecretChatActor.h b/td/telegram/SecretChatActor.h index 6560ad85f..01dd491ff 100644 --- a/td/telegram/SecretChatActor.h +++ b/td/telegram/SecretChatActor.h @@ -112,10 +112,11 @@ class SecretChatActor : public NetQueryCallback { SecretChatActor(int32 id, unique_ptr 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 chat); void create_chat(int32 user_id, int64 user_access_hash, int32 random_id, Promise promise); - void cancel_chat(Promise<> promise); + + void cancel_chat(bool delete_history, Promise<> promise); // Inbound messages // Logevent is created by SecretChatsManager, because it must contain qts @@ -637,7 +638,7 @@ class SecretChatActor : public NetQueryCallback { // DiscardEncryption void on_fatal_error(Status status); - void do_close_chat_impl(unique_ptr event); + void do_close_chat_impl(bool delete_history, uint64 log_event_id); void on_discard_encryption_result(NetQueryPtr result); // Other diff --git a/td/telegram/SecretChatsManager.cpp b/td/telegram/SecretChatsManager.cpp index e82b0b806..a4dd084e9 100644 --- a/td/telegram/SecretChatsManager.cpp +++ b/td/telegram/SecretChatsManager.cpp @@ -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)); } -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 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 message, @@ -235,8 +235,9 @@ void SecretChatsManager::replay_binlog_event(BinlogEvent &&binlog_event) { case log_event::SecretChatEvent::Type::CreateSecretChat: return replay_create_chat( unique_ptr(static_cast(message.release()))); + default: + LOG(FATAL) << "Unknown log event type " << tag("type", format::as_hex(static_cast(message->get_type()))); } - LOG(FATAL) << "Unknown log event type " << tag("type", format::as_hex(static_cast(message->get_type()))); } void SecretChatsManager::binlog_replay_finish() { diff --git a/td/telegram/SecretChatsManager.h b/td/telegram/SecretChatsManager.h index 655e9545d..04bf59870 100644 --- a/td/telegram/SecretChatsManager.h +++ b/td/telegram/SecretChatsManager.h @@ -30,13 +30,12 @@ class SecretChatsManager : public Actor { public: explicit SecretChatsManager(ActorShared<> parent); - // Proxy query to corrensponding SecretChatActor. - // Look for more info in SecretChatActor.h + // Proxy query to corrensponding SecretChatActor void on_update_chat(tl_object_ptr update); void on_new_message(tl_object_ptr &&message_ptr, Promise &&promise); void create_chat(int32 user_id, int64 user_access_hash, Promise 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 message, tl_object_ptr file, Promise<> promise); void send_message_action(SecretChatId secret_chat_id, tl_object_ptr action); diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index b4c319938..19cd4444b 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -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) { 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)); } diff --git a/td/telegram/UpdatesManager.cpp b/td/telegram/UpdatesManager.cpp index 47ca2e19b..f9ed0e73d 100644 --- a/td/telegram/UpdatesManager.cpp +++ b/td/telegram/UpdatesManager.cpp @@ -1643,7 +1643,7 @@ void UpdatesManager::add_pending_qts_update(tl_object_ptr int32 old_qts = get_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 " << oneline(to_string(update)); add_qts(qts - 1).set_value(Unit()); diff --git a/td/telegram/logevent/SecretChatEvent.h b/td/telegram/logevent/SecretChatEvent.h index c65b5d521..c69bdf46e 100644 --- a/td/telegram/logevent/SecretChatEvent.h +++ b/td/telegram/logevent/SecretChatEvent.h @@ -34,12 +34,8 @@ class SecretChatEvent : public LogEventBase { virtual Type get_type() const = 0; - static constexpr LogEvent::HandlerType get_handler_type() { - return LogEvent::HandlerType::SecretChats; - } - static constexpr int32 version() { - return 2; + return 3; } template @@ -354,7 +350,7 @@ class OutboundSecretMessage : public SecretChatLogEventBase(action); + bool has_action = action != nullptr; BEGIN_STORE_FLAGS(); STORE_FLAG(is_sent); STORE_FLAG(need_notify_user); @@ -414,21 +410,31 @@ class CloseSecretChat : public SecretChatLogEventBase { public: static constexpr Type type = SecretChatEvent::Type::CloseSecretChat; int32 chat_id = 0; + bool delete_history = false; template void store(StorerT &storer) const { using td::store; + BEGIN_STORE_FLAGS(); + STORE_FLAG(delete_history); + END_STORE_FLAGS(); store(chat_id, storer); } template void parse(ParserT &parser) { using td::parse; + if (parser.version() >= 3) { + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(delete_history); + END_PARSE_FLAGS(); + } parse(chat_id, parser); } 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) << "]"; } };