From f0333aa578e38aa45ca7f1c6c55251a34b8d4a1f Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 29 Jul 2021 21:43:03 +0300 Subject: [PATCH 1/7] Postpone updates in unknown channel instead of dropping. --- td/telegram/MessagesManager.cpp | 40 ++++++++++++++++++++------------- td/telegram/MessagesManager.h | 15 ++++++++----- 2 files changed, 33 insertions(+), 22 deletions(-) diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index d936bac7c..7cb206425 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -7260,6 +7260,12 @@ void MessagesManager::cancel_user_dialog_action(DialogId dialog_id, const Messag m->content->get_type()); } +void MessagesManager::add_postponed_channel_update(DialogId dialog_id, tl_object_ptr &&update, + int32 new_pts, int32 pts_count, Promise &&promise) { + postponed_channel_updates_[dialog_id].emplace( + new_pts, PendingPtsUpdate(std::move(update), new_pts, pts_count, std::move(promise))); +} + void MessagesManager::add_pending_channel_update(DialogId dialog_id, tl_object_ptr &&update, int32 new_pts, int32 pts_count, Promise &&promise, const char *source, bool is_postponed_update) { @@ -7307,10 +7313,10 @@ void MessagesManager::add_pending_channel_update(DialogId dialog_id, tl_object_p } if (new_pts > pts && pts != new_pts - pts_count) { - LOG(INFO) << "Found a gap in the " << dialog_id << " with pts = " << pts << ". new_pts = " << new_pts + LOG(INFO) << "Found a gap in unknown " << dialog_id << " with pts = " << pts << ". new_pts = " << new_pts << ", pts_count = " << pts_count << " in update from " << source; + add_postponed_channel_update(dialog_id, std::move(update), new_pts, pts_count, std::move(promise)); get_channel_difference(dialog_id, pts, true, "add_pending_channel_update 3"); - promise.set_value(Unit()); return; } @@ -7375,8 +7381,7 @@ void MessagesManager::add_pending_channel_update(DialogId dialog_id, tl_object_p if (running_get_channel_difference(dialog_id)) { LOG(INFO) << "Postpone channel update, because getChannelDifference is run"; - d->postponed_channel_updates.emplace(new_pts, - PendingPtsUpdate(std::move(update), new_pts, pts_count, std::move(promise))); + add_postponed_channel_update(dialog_id, std::move(update), new_pts, pts_count, std::move(promise)); return; } @@ -7385,9 +7390,7 @@ void MessagesManager::add_pending_channel_update(DialogId dialog_id, tl_object_p << ", pts_count = " << pts_count << " in update from " << source; if (d->was_opened || td_->contacts_manager_->get_channel_status(channel_id).is_member() || is_dialog_sponsored(d)) { - d->postponed_channel_updates.emplace( - new_pts, PendingPtsUpdate(std::move(update), new_pts, pts_count, std::move(promise))); - + add_postponed_channel_update(dialog_id, std::move(update), new_pts, pts_count, std::move(promise)); get_channel_difference(dialog_id, old_pts, true, "add_pending_channel_update pts mismatch"); } else { promise.set_value(Unit()); @@ -35864,17 +35867,19 @@ void MessagesManager::after_get_channel_difference(DialogId dialog_id, bool succ if (d != nullptr) { d->is_channel_difference_finished = true; bool have_access = have_input_peer(dialog_id, AccessRights::Read); - if (!d->postponed_channel_updates.empty()) { - LOG(INFO) << "Begin to apply postponed channel updates"; - while (!d->postponed_channel_updates.empty()) { - auto it = d->postponed_channel_updates.begin(); + auto updates_it = postponed_channel_updates_.find(dialog_id); + if (updates_it != postponed_channel_updates_.end()) { + auto &updates = updates_it->second; + LOG(INFO) << "Begin to apply " << updates.size() << " postponed channel updates"; + while (!updates.empty()) { + auto it = updates.begin(); auto update = std::move(it->second.update); auto update_pts = it->second.pts; auto update_pts_count = it->second.pts_count; auto promise = std::move(it->second.promise); - d->postponed_channel_updates.erase(it); + updates.erase(it); - auto old_size = d->postponed_channel_updates.size(); + auto old_size = updates.size(); auto update_id = update->get_id(); if (have_access) { add_pending_channel_update(dialog_id, std::move(update), update_pts, update_pts_count, std::move(promise), @@ -35882,7 +35887,7 @@ void MessagesManager::after_get_channel_difference(DialogId dialog_id, bool succ } else { promise.set_value(Unit()); } - if (d->postponed_channel_updates.size() != old_size || running_get_channel_difference(dialog_id)) { + if (updates.size() != old_size || running_get_channel_difference(dialog_id)) { if (success && update_pts - 10000 < d->pts && update_pts_count == 1) { // if getChannelDifference was successful and update pts is near channel pts, // we hope that the update eventually can be applied @@ -35893,10 +35898,10 @@ void MessagesManager::after_get_channel_difference(DialogId dialog_id, bool succ << " with pts " << d->pts << ", update pts is " << update_pts << ", update pts count is " << update_pts_count; vector> update_promises; - for (auto &postponed_update : d->postponed_channel_updates) { + for (auto &postponed_update : updates) { update_promises.push_back(std::move(postponed_update.second.promise)); } - d->postponed_channel_updates.clear(); + updates.clear(); for (auto &update_promise : update_promises) { update_promise.set_value(Unit()); } @@ -35904,6 +35909,9 @@ void MessagesManager::after_get_channel_difference(DialogId dialog_id, bool succ break; } } + if (updates.empty()) { + postponed_channel_updates_.erase(updates_it); + } LOG(INFO) << "Finish to apply postponed channel updates"; } diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index 56e7ff8d2..40a45425d 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -1240,12 +1240,11 @@ class MessagesManager final : public Actor { bool has_unload_timeout = false; bool is_channel_difference_finished = false; - int32 pts = 0; // for channels only - std::multimap postponed_channel_updates; // for channels only - int32 pending_read_channel_inbox_pts = 0; // for channels only - MessageId pending_read_channel_inbox_max_message_id; // for channels only - int32 pending_read_channel_inbox_server_unread_count = 0; // for channels only - std::unordered_map random_id_to_message_id; // for secret chats only + int32 pts = 0; // for channels only + int32 pending_read_channel_inbox_pts = 0; // for channels only + MessageId pending_read_channel_inbox_max_message_id; // for channels only + int32 pending_read_channel_inbox_server_unread_count = 0; // for channels only + std::unordered_map random_id_to_message_id; // for secret chats only MessageId last_assigned_message_id; // identifier of the last local or yet unsent message, assigned after // application start, used to guarantee that all assigned message identifiers @@ -1788,6 +1787,9 @@ class MessagesManager final : public Actor { bool can_set_game_score(DialogId dialog_id, const Message *m) const; + void add_postponed_channel_update(DialogId dialog_id, tl_object_ptr &&update, int32 new_pts, + int32 pts_count, Promise &&promise); + void process_channel_update(tl_object_ptr &&update); void on_message_edited(FullMessageId full_message_id, int32 pts); @@ -3239,6 +3241,7 @@ class MessagesManager final : public Actor { std::unordered_map active_get_channel_differencies_; std::unordered_map get_channel_difference_to_log_event_id_; std::unordered_map channel_get_difference_retry_timeouts_; + std::unordered_map, DialogIdHash> postponed_channel_updates_; MultiTimeout channel_get_difference_timeout_{"ChannelGetDifferenceTimeout"}; MultiTimeout channel_get_difference_retry_timeout_{"ChannelGetDifferenceRetryTimeout"}; From c2028aed4f62a89efb54d4f1327d9ad650ae2ea0 Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 29 Jul 2021 23:39:07 +0300 Subject: [PATCH 2/7] Add limit on maximum videoNote size. --- td/telegram/ConfigManager.cpp | 5 ++++- td/telegram/MessagesManager.cpp | 2 +- td/telegram/Td.cpp | 2 ++ td/telegram/cli.cpp | 2 +- td/telegram/files/FileManager.cpp | 15 ++++++++++----- td/telegram/files/FileType.cpp | 1 + 6 files changed, 19 insertions(+), 8 deletions(-) diff --git a/td/telegram/ConfigManager.cpp b/td/telegram/ConfigManager.cpp index 028033b76..4d767ae38 100644 --- a/td/telegram/ConfigManager.cpp +++ b/td/telegram/ConfigManager.cpp @@ -1684,7 +1684,7 @@ void ConfigManager::process_app_config(tl_object_ptr &c for (auto &video_note_setting : video_note_settings) { CHECK(video_note_setting != nullptr); if (video_note_setting->key_ != "diameter" && video_note_setting->key_ != "video_bitrate" && - video_note_setting->key_ != "audio_bitrate") { + video_note_setting->key_ != "audio_bitrate" && video_note_setting->key_ != "max_size") { continue; } if (video_note_setting->value_->get_id() == telegram_api::jsonNumber::ID) { @@ -1700,6 +1700,9 @@ void ConfigManager::process_app_config(tl_object_ptr &c if (video_note_setting->key_ == "audio_bitrate") { G()->shared_config().set_option_integer("suggested_video_note_audio_bitrate", setting_value); } + if (video_note_setting->key_ == "max_size") { + G()->shared_config().set_option_integer("video_note_size_max", setting_value); + } } } else { LOG(ERROR) << "Receive unexpected video note setting " << to_string(video_note_setting); diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 7cb206425..67affdbff 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -35839,7 +35839,7 @@ void MessagesManager::on_get_channel_difference( } if (!is_final) { - LOG_IF(ERROR, timeout > 0) << "Have timeout in not final ChannelDifference in " << dialog_id; + LOG_IF(ERROR, timeout > 0) << "Have timeout in nonfinal ChannelDifference in " << dialog_id; get_channel_difference(dialog_id, d->pts, true, "on_get_channel_difference"); return; } diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index b02ecebf4..63619d3f8 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -3565,6 +3565,8 @@ bool Td::is_internal_config_option(Slice name) { name == "rating_e_decay" || name == "recent_stickers_limit"; case 's': return name == "saved_animations_limit"; + case 'v': + return name == "video_note_size_max"; case 'w': return name == "webfile_dc_id"; default: diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index 995e774d8..4362f251f 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -3624,7 +3624,7 @@ class CliClient final : public Actor { string video_path; get_args(args, chat_id, video_path); send_message(chat_id, - td_api::make_object(as_input_file(video_path), nullptr, 1, 5)); + td_api::make_object(as_input_file(video_path), nullptr, 10, 5)); } else if (op == "svenue") { string chat_id; string latitude; diff --git a/td/telegram/files/FileManager.cpp b/td/telegram/files/FileManager.cpp index 7bfb61cf3..e4cf97325 100644 --- a/td/telegram/files/FileManager.cpp +++ b/td/telegram/files/FileManager.cpp @@ -920,6 +920,7 @@ bool FileManager::are_modification_times_equal(int64 old_mtime, int64 new_mtime) Status FileManager::check_local_location(FullLocalFileLocation &location, int64 &size, bool skip_file_size_checks) { constexpr int64 MAX_THUMBNAIL_SIZE = 200 * (1 << 10) - 1 /* 200 KB - 1 B */; constexpr int64 MAX_PHOTO_SIZE = 10 * (1 << 20) /* 10 MB */; + constexpr int64 DEFAULT_VIDEO_NOTE_SIZE_MAX = 12 * (1 << 20) /* 12 MB */; if (location.path_.empty()) { return Status::Error(400, "File must have non-empty path"); @@ -967,13 +968,17 @@ Status FileManager::check_local_location(FullLocalFileLocation &location, int64 return Status::Error(400, PSLICE() << "File \"" << location.path_ << "\" is too big for a thumbnail " << tag("size", format::as_size(size))); } - if (location.file_type_ == FileType::Photo && size > MAX_PHOTO_SIZE) { - return Status::Error(400, PSLICE() << "File \"" << location.path_ << "\" is too big for a photo " - << tag("size", format::as_size(size))); - } if (size > MAX_FILE_SIZE) { + return Status::Error(400, PSLICE() << "File \"" << location.path_ << "\" of size " << size << " bytes is too big"); + } + if (location.file_type_ == FileType::Photo && size > MAX_PHOTO_SIZE) { return Status::Error( - 400, PSLICE() << "File \"" << location.path_ << "\" is too big " << tag("size", format::as_size(size))); + 400, PSLICE() << "File \"" << location.path_ << "\" of size " << size << " bytes is too big for a photo"); + } + if (location.file_type_ == FileType::VideoNote && + size > G()->shared_config().get_option_integer("video_note_size_max", DEFAULT_VIDEO_NOTE_SIZE_MAX)) { + return Status::Error( + 400, PSLICE() << "File \"" << location.path_ << "\" of size " << size << " bytes is too big for a video note"); } return Status::OK(); } diff --git a/td/telegram/files/FileType.cpp b/td/telegram/files/FileType.cpp index 2c1bc50d7..24a719843 100644 --- a/td/telegram/files/FileType.cpp +++ b/td/telegram/files/FileType.cpp @@ -182,6 +182,7 @@ bool is_file_big(FileType file_type, int64 expected_size) { case FileType::ProfilePhoto: case FileType::Photo: case FileType::EncryptedThumbnail: + case FileType::VideoNote: return false; default: break; From 50052f63ef87add978870cc3592b506705528293 Mon Sep 17 00:00:00 2001 From: levlam Date: Fri, 30 Jul 2021 04:49:04 +0300 Subject: [PATCH 3/7] Don't update message if edit_date decreased. --- td/telegram/MessagesManager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 67affdbff..31712e438 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -32038,7 +32038,7 @@ MessagesManager::Message *MessagesManager::add_message_to_dialog(Dialog *d, uniq if (*need_update) { *need_update = false; if (!G()->parameters().use_message_db) { - // can happen for bots if the message is received first through getMessage in an unknown chat without + // can happen if the message is received first through getMessage in an unknown chat without // last_new_message_id and only after that received through getDifference or getChannelDifference if (d->last_new_message_id.is_valid()) { LOG(ERROR) << "Receive again " << (message->is_outgoing ? "outgoing" : "incoming") @@ -32055,7 +32055,7 @@ MessagesManager::Message *MessagesManager::add_message_to_dialog(Dialog *d, uniq message->have_previous = false; message->have_next = false; } - if (!message->from_database) { + if (!message->from_database && (from_update || message->edit_date >= m->edit_date)) { const int32 INDEX_MASK_MASK = ~message_search_filter_index_mask(MessageSearchFilter::UnreadMention); auto old_index_mask = get_message_index_mask(dialog_id, m) & INDEX_MASK_MASK; bool was_deleted = delete_active_live_location(dialog_id, m); From ed15c1078b6a675adc8e92a7c2eb4b7f6cb2044d Mon Sep 17 00:00:00 2001 From: levlam Date: Fri, 30 Jul 2021 04:56:39 +0300 Subject: [PATCH 4/7] Apply postponed channel updates even Dialog wasn't created. --- td/telegram/MessagesManager.cpp | 98 +++++++++++++++++---------------- 1 file changed, 50 insertions(+), 48 deletions(-) diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 31712e438..7776f7ce5 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -35864,56 +35864,58 @@ void MessagesManager::after_get_channel_difference(DialogId dialog_id, bool succ } auto d = get_dialog(dialog_id); + bool have_access = have_input_peer(dialog_id, AccessRights::Read); + auto pts = d != nullptr ? d->pts : load_channel_pts(dialog_id); + auto updates_it = postponed_channel_updates_.find(dialog_id); + if (updates_it != postponed_channel_updates_.end()) { + auto &updates = updates_it->second; + LOG(INFO) << "Begin to apply " << updates.size() << " postponed channel updates"; + while (!updates.empty()) { + auto it = updates.begin(); + auto update = std::move(it->second.update); + auto update_pts = it->second.pts; + auto update_pts_count = it->second.pts_count; + auto promise = std::move(it->second.promise); + updates.erase(it); + + auto old_size = updates.size(); + auto update_id = update->get_id(); + if (have_access) { + add_pending_channel_update(dialog_id, std::move(update), update_pts, update_pts_count, std::move(promise), + "apply postponed channel updates", true); + } else { + promise.set_value(Unit()); + } + if (updates.size() != old_size || running_get_channel_difference(dialog_id)) { + if (success && update_pts - 10000 < pts && update_pts_count == 1) { + // if getChannelDifference was successful and update pts is near channel pts, + // we hope that the update eventually can be applied + LOG(INFO) << "Can't apply postponed channel updates"; + } else { + // otherwise protect from getChannelDifference repeating calls by dropping postponed updates + LOG(WARNING) << "Failed to apply postponed updates of type " << update_id << " in " << dialog_id + << " with pts " << pts << ", update pts is " << update_pts << ", update pts count is " + << update_pts_count; + vector> update_promises; + for (auto &postponed_update : updates) { + update_promises.push_back(std::move(postponed_update.second.promise)); + } + updates.clear(); + for (auto &update_promise : update_promises) { + update_promise.set_value(Unit()); + } + } + break; + } + } + if (updates.empty()) { + postponed_channel_updates_.erase(updates_it); + } + LOG(INFO) << "Finish to apply postponed channel updates"; + } + if (d != nullptr) { d->is_channel_difference_finished = true; - bool have_access = have_input_peer(dialog_id, AccessRights::Read); - auto updates_it = postponed_channel_updates_.find(dialog_id); - if (updates_it != postponed_channel_updates_.end()) { - auto &updates = updates_it->second; - LOG(INFO) << "Begin to apply " << updates.size() << " postponed channel updates"; - while (!updates.empty()) { - auto it = updates.begin(); - auto update = std::move(it->second.update); - auto update_pts = it->second.pts; - auto update_pts_count = it->second.pts_count; - auto promise = std::move(it->second.promise); - updates.erase(it); - - auto old_size = updates.size(); - auto update_id = update->get_id(); - if (have_access) { - add_pending_channel_update(dialog_id, std::move(update), update_pts, update_pts_count, std::move(promise), - "apply postponed channel updates", true); - } else { - promise.set_value(Unit()); - } - if (updates.size() != old_size || running_get_channel_difference(dialog_id)) { - if (success && update_pts - 10000 < d->pts && update_pts_count == 1) { - // if getChannelDifference was successful and update pts is near channel pts, - // we hope that the update eventually can be applied - LOG(INFO) << "Can't apply postponed channel updates"; - } else { - // otherwise protect from getChannelDifference repeating calls by dropping postponed updates - LOG(WARNING) << "Failed to apply postponed updates of type " << update_id << " in " << dialog_id - << " with pts " << d->pts << ", update pts is " << update_pts << ", update pts count is " - << update_pts_count; - vector> update_promises; - for (auto &postponed_update : updates) { - update_promises.push_back(std::move(postponed_update.second.promise)); - } - updates.clear(); - for (auto &update_promise : update_promises) { - update_promise.set_value(Unit()); - } - } - break; - } - } - if (updates.empty()) { - postponed_channel_updates_.erase(updates_it); - } - LOG(INFO) << "Finish to apply postponed channel updates"; - } if (d->message_notification_group.group_id.is_valid()) { send_closure_later(G()->notification_manager(), &NotificationManager::after_get_chat_difference, From fba5f2fa04c8117eb7361b5c02000b17aaf7cae6 Mon Sep 17 00:00:00 2001 From: levlam Date: Fri, 30 Jul 2021 05:40:13 +0300 Subject: [PATCH 5/7] Simplify on_get_history using that d != nullptr since 31 Aug 2016. --- td/telegram/MessagesManager.cpp | 60 +++++++++++---------------------- 1 file changed, 20 insertions(+), 40 deletions(-) diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 7776f7ce5..63167745d 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -9266,10 +9266,10 @@ void MessagesManager::on_get_history(DialogId dialog_id, MessageId from_message_ CHECK(!from_message_id.is_scheduled()); Dialog *d = get_dialog(dialog_id); + CHECK(d != nullptr); MessageId last_received_message_id = messages.empty() ? MessageId() : get_message_id(messages[0], false); - if (d != nullptr && old_last_new_message_id < d->last_new_message_id && - (from_the_end || old_last_new_message_id < from_message_id) && + if (old_last_new_message_id < d->last_new_message_id && (from_the_end || old_last_new_message_id < from_message_id) && last_received_message_id < d->last_new_message_id) { // new server messages were added to the dialog since the request was sent, but weren't received // they should have been received, so we must repeat the request to get them @@ -9286,19 +9286,17 @@ void MessagesManager::on_get_history(DialogId dialog_id, MessageId from_message_ bool have_full_history = from_the_end && narrow_cast(messages.size()) < limit && messages.size() <= 1; if (messages.empty()) { - if (d != nullptr) { - if (have_full_history) { - d->have_full_history = true; - on_dialog_updated(dialog_id, "set have_full_history"); - } + if (have_full_history) { + d->have_full_history = true; + on_dialog_updated(dialog_id, "set have_full_history"); + } - if (from_the_end && d->have_full_history && d->messages == nullptr) { - if (!d->last_database_message_id.is_valid()) { - set_dialog_is_empty(d, "on_get_history empty"); - } else { - LOG(INFO) << "Skip marking " << dialog_id << " as empty, because it probably has messages from " - << d->first_database_message_id << " to " << d->last_database_message_id << " in the database"; - } + if (from_the_end && d->have_full_history && d->messages == nullptr) { + if (!d->last_database_message_id.is_valid()) { + set_dialog_is_empty(d, "on_get_history empty"); + } else { + LOG(INFO) << "Skip marking " << dialog_id << " as empty, because it probably has messages from " + << d->first_database_message_id << " to " << d->last_database_message_id << " in the database"; } } @@ -9329,7 +9327,6 @@ void MessagesManager::on_get_history(DialogId dialog_id, MessageId from_message_ } } - // be aware that dialog may not yet exist // be aware that returned messages are guaranteed to be consecutive messages, but if !from_the_end they // may be older (if some messages was deleted) or newer (if some messages were added) than an expected answer // be aware that any subset of the returned messages may be already deleted and returned as MessageEmpty @@ -9338,7 +9335,7 @@ void MessagesManager::on_get_history(DialogId dialog_id, MessageId from_message_ MessageId last_added_message_id; bool have_next = false; - if (narrow_cast(messages.size()) < limit + offset && messages.size() <= 1 && d != nullptr) { + if (narrow_cast(messages.size()) < limit + offset && messages.size() <= 1) { MessageId first_received_message_id = get_message_id(messages.back(), false); if (first_received_message_id >= from_message_id && d->first_database_message_id.is_valid() && first_received_message_id >= d->first_database_message_id) { @@ -9347,20 +9344,12 @@ void MessagesManager::on_get_history(DialogId dialog_id, MessageId from_message_ } } - bool prev_have_full_history = false; - MessageId prev_last_new_message_id; - MessageId prev_first_database_message_id; - MessageId prev_last_database_message_id; - MessageId prev_last_message_id; - if (d != nullptr) { - prev_last_new_message_id = d->last_new_message_id; - prev_first_database_message_id = d->first_database_message_id; - prev_last_database_message_id = d->last_database_message_id; - prev_last_message_id = d->last_message_id; - prev_have_full_history = d->have_full_history; - } - - if (from_the_end && d != nullptr) { + bool prev_have_full_history = d->have_full_history; + MessageId prev_last_new_message_id = d->last_new_message_id; + MessageId prev_first_database_message_id = d->first_database_message_id; + MessageId prev_last_database_message_id = d->last_database_message_id; + MessageId prev_last_message_id = d->last_message_id; + if (from_the_end) { // delete all server messages with ID > last_received_message_id // there were no new messages received after the getHistory request was sent, so they are already deleted message vector message_ids; @@ -9402,7 +9391,7 @@ void MessagesManager::on_get_history(DialogId dialog_id, MessageId from_message_ } for (auto &message : messages) { - if (!have_next && from_the_end && d != nullptr && get_message_id(message, false) < d->last_message_id) { + if (!have_next && from_the_end && get_message_id(message, false) < d->last_message_id) { // last message in the dialog should be attached to the next message if there is some have_next = true; } @@ -9423,10 +9412,6 @@ void MessagesManager::on_get_history(DialogId dialog_id, MessageId from_message_ } if (!have_next) { - if (d == nullptr) { - d = get_dialog(dialog_id); - CHECK(d != nullptr); - } have_next = true; } else if (first_added_message_id.is_valid()) { Message *next_message = get_message(d, first_added_message_id); @@ -9445,11 +9430,6 @@ void MessagesManager::on_get_history(DialogId dialog_id, MessageId from_message_ } } - if (d == nullptr) { - promise.set_value(Unit()); - return; - } - if (have_full_history) { d->have_full_history = true; on_dialog_updated(dialog_id, "set have_full_history 2"); From 77c20cd82ff651a440341d8580228d7f4e971abd Mon Sep 17 00:00:00 2001 From: levlam Date: Fri, 30 Jul 2021 05:58:24 +0300 Subject: [PATCH 6/7] Run channelDifference before messages can be added to the chat. --- td/telegram/MessagesManager.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 63167745d..91175975f 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -35335,8 +35335,11 @@ bool MessagesManager::need_channel_difference_to_add_message(DialogId dialog_id, } Dialog *d = get_dialog_force(dialog_id, "need_channel_difference_to_add_message"); - if (d == nullptr || d->last_new_message_id == MessageId()) { - return false; + if (d == nullptr) { + return load_channel_pts(dialog_id) > 0; + } + if (d->last_new_message_id == MessageId()) { + return d->pts > 0 && !d->is_channel_difference_finished; } return get_message_id(message_ptr, false) > d->last_new_message_id; @@ -35346,7 +35349,7 @@ void MessagesManager::run_after_channel_difference(DialogId dialog_id, Promise Date: Fri, 30 Jul 2021 06:04:31 +0300 Subject: [PATCH 7/7] Save is_channel_difference_finished for uncreated dialogs. --- td/telegram/MessagesManager.cpp | 7 ++++++- td/telegram/MessagesManager.h | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 91175975f..244ef1453 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -33825,6 +33825,9 @@ MessagesManager::Dialog *MessagesManager::add_new_dialog(unique_ptr &&d, if (td_->auth_manager_->is_bot()) { d->notification_settings.is_synchronized = true; } + if (is_channel_difference_finished_.erase(dialog_id)) { + d->is_channel_difference_finished = true; + } unique_ptr last_database_message = std::move(d->messages); MessageId last_database_message_id = d->last_database_message_id; @@ -35336,7 +35339,7 @@ bool MessagesManager::need_channel_difference_to_add_message(DialogId dialog_id, Dialog *d = get_dialog_force(dialog_id, "need_channel_difference_to_add_message"); if (d == nullptr) { - return load_channel_pts(dialog_id) > 0; + return load_channel_pts(dialog_id) > 0 && !is_channel_difference_finished_.count(dialog_id); } if (d->last_new_message_id == MessageId()) { return d->pts > 0 && !d->is_channel_difference_finished; @@ -35913,6 +35916,8 @@ void MessagesManager::after_get_channel_difference(DialogId dialog_id, bool succ (d->order != DEFAULT_ORDER || is_dialog_sponsored(d))) { get_history_from_the_end_impl(d, true, false, Auto()); } + } else { + is_channel_difference_finished_.insert(dialog_id); } if (postponed_chat_read_inbox_updates_.erase(dialog_id) > 0) { diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index 40a45425d..1dda031d4 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -3242,6 +3242,7 @@ class MessagesManager final : public Actor { std::unordered_map get_channel_difference_to_log_event_id_; std::unordered_map channel_get_difference_retry_timeouts_; std::unordered_map, DialogIdHash> postponed_channel_updates_; + std::unordered_set is_channel_difference_finished_; MultiTimeout channel_get_difference_timeout_{"ChannelGetDifferenceTimeout"}; MultiTimeout channel_get_difference_retry_timeout_{"ChannelGetDifferenceRetryTimeout"};