Improve encryptedChatDiscarded handling.
This commit is contained in:
parent
cc8c0cbe64
commit
091d08b6a9
@ -115,7 +115,7 @@ void SecretChatActor::on_result_resendable(NetQueryPtr net_query, Promise<NetQue
|
|||||||
auto key = UniqueId::extract_key(net_query->id());
|
auto key = UniqueId::extract_key(net_query->id());
|
||||||
if (close_flag_) {
|
if (close_flag_) {
|
||||||
if (key == static_cast<uint8>(QueryType::DiscardEncryption)) {
|
if (key == static_cast<uint8>(QueryType::DiscardEncryption)) {
|
||||||
on_discard_encryption_result(std::move(net_query));
|
discard_encryption_promise_.set_value(Unit());
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -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(event->delete_history, event->log_event_id());
|
do_close_chat_impl(event->delete_history, event->is_already_discarded, event->log_event_id(), Promise<Unit>());
|
||||||
}
|
}
|
||||||
|
|
||||||
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(false, Promise<>());
|
cancel_chat(false, false, Promise<>());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SecretChatActor::cancel_chat(bool delete_history, Promise<> promise) {
|
void SecretChatActor::cancel_chat(bool delete_history, bool is_already_discarded, Promise<> promise) {
|
||||||
if (close_flag_) {
|
if (close_flag_) {
|
||||||
promise.set_value(Unit());
|
promise.set_value(Unit());
|
||||||
return;
|
return;
|
||||||
@ -737,11 +737,11 @@ void SecretChatActor::cancel_chat(bool delete_history, Promise<> promise) {
|
|||||||
event->chat_id = auth_state_.id;
|
event->chat_id = auth_state_.id;
|
||||||
auto 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), delete_history, log_event_id,
|
auto on_sync = PromiseCreator::lambda([actor_id = actor_id(this), delete_history, is_already_discarded, log_event_id,
|
||||||
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, delete_history, log_event_id);
|
send_closure(actor_id, &SecretChatActor::do_close_chat_impl, delete_history, is_already_discarded, log_event_id,
|
||||||
promise.set_value(Unit());
|
std::move(promise));
|
||||||
} 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(), "cancel_chat");
|
send_closure(actor_id, &SecretChatActor::on_promise_error, result.move_as_error(), "cancel_chat");
|
||||||
@ -752,25 +752,56 @@ void SecretChatActor::cancel_chat(bool delete_history, Promise<> promise) {
|
|||||||
yield();
|
yield();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SecretChatActor::do_close_chat_impl(bool delete_history, uint64 log_event_id) {
|
void SecretChatActor::do_close_chat_impl(bool delete_history, bool is_already_discarded, uint64 log_event_id,
|
||||||
|
Promise<Unit> &&promise) {
|
||||||
close_flag_ = true;
|
close_flag_ = true;
|
||||||
close_log_event_id_ = log_event_id;
|
|
||||||
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_);
|
||||||
context_->secret_chat_db()->erase_value(config_state_);
|
context_->secret_chat_db()->erase_value(config_state_);
|
||||||
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;
|
|
||||||
|
MultiPromiseActorSafe mpas{"DeleteMessagesFromServerMultiPromiseActor"};
|
||||||
|
mpas.add_promise(
|
||||||
|
PromiseCreator::lambda([actor_id = actor_id(this), log_event_id, promise = std::move(promise)](Unit) mutable {
|
||||||
|
send_closure(actor_id, &SecretChatActor::on_closed, log_event_id, std::move(promise));
|
||||||
|
}));
|
||||||
|
|
||||||
|
auto lock = mpas.get_promise();
|
||||||
|
|
||||||
if (delete_history) {
|
if (delete_history) {
|
||||||
flags |= telegram_api::messages_discardEncryption::DELETE_HISTORY_MASK;
|
context_->on_flush_history(MessageId::max(), mpas.get_promise());
|
||||||
}
|
}
|
||||||
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();
|
||||||
|
|
||||||
context_->send_net_query(std::move(query), actor_shared(this), true);
|
if (!is_already_discarded) {
|
||||||
|
int32 flags = 0;
|
||||||
|
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));
|
||||||
|
query->total_timeout_limit_ = 60 * 60 * 24 * 365;
|
||||||
|
context_->send_net_query(std::move(query), actor_shared(this), true);
|
||||||
|
discard_encryption_promise_ = mpas.get_promise();
|
||||||
|
}
|
||||||
|
|
||||||
|
lock.set_value(Unit());
|
||||||
|
}
|
||||||
|
|
||||||
|
void SecretChatActor::on_closed(uint64 log_event_id, Promise<Unit> &&promise) {
|
||||||
|
CHECK(close_flag_);
|
||||||
|
if (context_->close_flag()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG(INFO) << "Finish closing";
|
||||||
|
context_->secret_chat_db()->erase_value(auth_state_);
|
||||||
|
binlog_erase(context_->binlog(), log_event_id);
|
||||||
|
promise.set_value(Unit());
|
||||||
|
// skip flush
|
||||||
|
stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SecretChatActor::do_create_chat_impl(unique_ptr<log_event::CreateSecretChat> event) {
|
void SecretChatActor::do_create_chat_impl(unique_ptr<log_event::CreateSecretChat> event) {
|
||||||
@ -793,18 +824,6 @@ void SecretChatActor::do_create_chat_impl(unique_ptr<log_event::CreateSecretChat
|
|||||||
create_log_event_id_ = 0;
|
create_log_event_id_ = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void SecretChatActor::on_discard_encryption_result(NetQueryPtr result) {
|
|
||||||
CHECK(close_flag_);
|
|
||||||
CHECK(close_log_event_id_ != 0);
|
|
||||||
if (context_->close_flag()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
LOG(INFO) << "Got result for messages.discardEncryption";
|
|
||||||
context_->secret_chat_db()->erase_value(auth_state_);
|
|
||||||
binlog_erase(context_->binlog(), close_log_event_id_);
|
|
||||||
// skip flush
|
|
||||||
stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
telegram_api::object_ptr<telegram_api::inputUser> SecretChatActor::get_input_user() {
|
telegram_api::object_ptr<telegram_api::inputUser> SecretChatActor::get_input_user() {
|
||||||
return telegram_api::make_object<telegram_api::inputUser>(auth_state_.user_id, auth_state_.user_access_hash);
|
return telegram_api::make_object<telegram_api::inputUser>(auth_state_.user_id, auth_state_.user_access_hash);
|
||||||
@ -1904,7 +1923,8 @@ Status SecretChatActor::on_update_chat(telegram_api::encryptedChat &update) {
|
|||||||
return Status::OK();
|
return Status::OK();
|
||||||
}
|
}
|
||||||
Status SecretChatActor::on_update_chat(telegram_api::encryptedChatDiscarded &update) {
|
Status SecretChatActor::on_update_chat(telegram_api::encryptedChatDiscarded &update) {
|
||||||
return Status::Error("Chat discarded");
|
cancel_chat(update.history_deleted_, true, Promise<Unit>());
|
||||||
|
return Status::OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
Status SecretChatActor::on_update_chat(NetQueryPtr query) {
|
Status SecretChatActor::on_update_chat(NetQueryPtr query) {
|
||||||
|
@ -116,7 +116,7 @@ class SecretChatActor : public NetQueryCallback {
|
|||||||
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(bool delete_history, Promise<> promise);
|
void cancel_chat(bool delete_history, bool is_already_discarded, 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
|
||||||
@ -462,7 +462,7 @@ class SecretChatActor : public NetQueryCallback {
|
|||||||
|
|
||||||
bool binlog_replay_finish_flag_ = false;
|
bool binlog_replay_finish_flag_ = false;
|
||||||
bool close_flag_ = false;
|
bool close_flag_ = false;
|
||||||
LogEvent::Id close_log_event_id_ = 0;
|
Promise<Unit> discard_encryption_promise_;
|
||||||
|
|
||||||
LogEvent::Id create_log_event_id_ = 0;
|
LogEvent::Id create_log_event_id_ = 0;
|
||||||
|
|
||||||
@ -638,8 +638,8 @@ class SecretChatActor : public NetQueryCallback {
|
|||||||
|
|
||||||
// DiscardEncryption
|
// DiscardEncryption
|
||||||
void on_fatal_error(Status status);
|
void on_fatal_error(Status status);
|
||||||
void do_close_chat_impl(bool delete_history, uint64 log_event_id);
|
void do_close_chat_impl(bool delete_history, bool is_already_discarded, uint64 log_event_id, Promise<Unit> &&promise);
|
||||||
void on_discard_encryption_result(NetQueryPtr result);
|
void on_closed(uint64 log_event_id, Promise<Unit> &&promise);
|
||||||
|
|
||||||
// Other
|
// Other
|
||||||
template <class T>
|
template <class T>
|
||||||
|
@ -109,7 +109,7 @@ void SecretChatsManager::create_chat(int32 user_id, int64 user_access_hash, Prom
|
|||||||
void SecretChatsManager::cancel_chat(SecretChatId secret_chat_id, bool delete_history, 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, delete_history, std::move(safe_promise));
|
send_closure(actor, &SecretChatActor::cancel_chat, delete_history, false, 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,
|
||||||
|
@ -411,12 +411,14 @@ class CloseSecretChat : public SecretChatLogEventBase<CloseSecretChat> {
|
|||||||
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;
|
bool delete_history = false;
|
||||||
|
bool is_already_discarded = 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();
|
BEGIN_STORE_FLAGS();
|
||||||
STORE_FLAG(delete_history);
|
STORE_FLAG(delete_history);
|
||||||
|
STORE_FLAG(is_already_discarded);
|
||||||
END_STORE_FLAGS();
|
END_STORE_FLAGS();
|
||||||
store(chat_id, storer);
|
store(chat_id, storer);
|
||||||
}
|
}
|
||||||
@ -427,6 +429,7 @@ class CloseSecretChat : public SecretChatLogEventBase<CloseSecretChat> {
|
|||||||
if (parser.version() >= 3) {
|
if (parser.version() >= 3) {
|
||||||
BEGIN_PARSE_FLAGS();
|
BEGIN_PARSE_FLAGS();
|
||||||
PARSE_FLAG(delete_history);
|
PARSE_FLAG(delete_history);
|
||||||
|
PARSE_FLAG(is_already_discarded);
|
||||||
END_PARSE_FLAGS();
|
END_PARSE_FLAGS();
|
||||||
}
|
}
|
||||||
parse(chat_id, parser);
|
parse(chat_id, parser);
|
||||||
@ -434,7 +437,7 @@ class CloseSecretChat : public SecretChatLogEventBase<CloseSecretChat> {
|
|||||||
|
|
||||||
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) << "]";
|
<< tag("delete_history", delete_history) << tag("is_already_discarded", is_already_discarded) << "]";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user