Merge remote-tracking branch 'td/master'

This commit is contained in:
Andrea Cavalli 2022-03-23 19:08:37 +01:00
commit 86159c5a7d
7 changed files with 214 additions and 189 deletions

View File

@ -18,10 +18,10 @@
namespace td {
AdministratorRights::AdministratorRights(bool can_manage_dialog, bool can_change_info, bool can_post_messages,
bool can_edit_messages, bool can_delete_messages, bool can_invite_users,
bool can_restrict_members, bool can_pin_messages, bool can_promote_members,
bool can_manage_calls) {
AdministratorRights::AdministratorRights(bool is_anonymous, bool can_manage_dialog, bool can_change_info,
bool can_post_messages, bool can_edit_messages, bool can_delete_messages,
bool can_invite_users, bool can_restrict_members, bool can_pin_messages,
bool can_promote_members, bool can_manage_calls) {
flags_ = (static_cast<uint32>(can_manage_dialog) * CAN_MANAGE_DIALOG) |
(static_cast<uint32>(can_change_info) * CAN_CHANGE_INFO_AND_SETTINGS) |
(static_cast<uint32>(can_post_messages) * CAN_POST_MESSAGES) |
@ -31,14 +31,14 @@ AdministratorRights::AdministratorRights(bool can_manage_dialog, bool can_change
(static_cast<uint32>(can_restrict_members) * CAN_RESTRICT_MEMBERS) |
(static_cast<uint32>(can_pin_messages) * CAN_PIN_MESSAGES) |
(static_cast<uint32>(can_promote_members) * CAN_PROMOTE_MEMBERS) |
(static_cast<uint32>(can_manage_calls) * CAN_MANAGE_CALLS);
(static_cast<uint32>(can_manage_calls) * CAN_MANAGE_CALLS) |
(static_cast<uint32>(is_anonymous) * IS_ANONYMOUS);
if (flags_ != 0) {
flags_ |= CAN_MANAGE_DIALOG;
}
}
telegram_api::object_ptr<telegram_api::chatAdminRights> AdministratorRights::get_chat_admin_rights(
bool is_anonymous) const {
telegram_api::object_ptr<telegram_api::chatAdminRights> AdministratorRights::get_chat_admin_rights() const {
int32 flags = 0;
if ((flags_ & CAN_CHANGE_INFO_AND_SETTINGS) != 0) {
flags |= telegram_api::chatAdminRights::CHANGE_INFO_MASK;
@ -70,8 +70,7 @@ telegram_api::object_ptr<telegram_api::chatAdminRights> AdministratorRights::get
if (can_manage_dialog()) {
flags |= telegram_api::chatAdminRights::OTHER_MASK;
}
if (is_anonymous) {
if (is_anonymous()) {
flags |= telegram_api::chatAdminRights::ANONYMOUS_MASK;
}
@ -120,6 +119,9 @@ StringBuilder &operator<<(StringBuilder &string_builder, const AdministratorRigh
if (status.can_manage_calls()) {
string_builder << "(voice chat)";
}
if (status.is_anonymous()) {
string_builder << "(anonymous)";
}
return string_builder;
}
@ -247,27 +249,17 @@ int32 DialogParticipantStatus::fix_until_date(int32 date) {
return date;
}
DialogParticipantStatus DialogParticipantStatus::Creator(bool is_member, bool is_anonymous, string rank) {
DialogParticipantStatus DialogParticipantStatus::Creator(bool is_member, bool is_anonymous, string &&rank) {
return DialogParticipantStatus(Type::Creator,
AdministratorRights::ALL_ADMINISTRATOR_RIGHTS |
RestrictedRights::ALL_RESTRICTED_RIGHTS | (is_member ? IS_MEMBER : 0) |
(is_anonymous ? IS_ANONYMOUS : 0),
(is_anonymous ? AdministratorRights::IS_ANONYMOUS : 0),
0, std::move(rank));
}
DialogParticipantStatus DialogParticipantStatus::Administrator(bool is_anonymous, string rank, bool can_be_edited,
bool can_manage_dialog, bool can_change_info,
bool can_post_messages, bool can_edit_messages,
bool can_delete_messages, bool can_invite_users,
bool can_restrict_members, bool can_pin_messages,
bool can_promote_members, bool can_manage_calls) {
uint32 flags = AdministratorRights(can_manage_dialog, can_change_info, can_post_messages, can_edit_messages,
can_delete_messages, can_invite_users, can_restrict_members, can_pin_messages,
can_promote_members, can_manage_calls)
.flags_;
if (is_anonymous) {
flags |= IS_ANONYMOUS | AdministratorRights::CAN_MANAGE_DIALOG;
}
DialogParticipantStatus DialogParticipantStatus::Administrator(AdministratorRights administrator_rights, string &&rank,
bool can_be_edited) {
uint32 flags = administrator_rights.flags_;
if (flags == 0) {
return Member();
}
@ -278,22 +270,29 @@ DialogParticipantStatus DialogParticipantStatus::Administrator(bool is_anonymous
std::move(rank));
}
DialogParticipantStatus DialogParticipantStatus::Administrator(bool is_anonymous, string &&rank, bool can_be_edited,
bool can_manage_dialog, bool can_change_info,
bool can_post_messages, bool can_edit_messages,
bool can_delete_messages, bool can_invite_users,
bool can_restrict_members, bool can_pin_messages,
bool can_promote_members, bool can_manage_calls) {
auto administrator_rights = AdministratorRights(
is_anonymous, can_manage_dialog, can_change_info, can_post_messages, can_edit_messages, can_delete_messages,
can_invite_users, can_restrict_members, can_pin_messages, can_promote_members, can_manage_calls);
return Administrator(administrator_rights, std::move(rank), can_be_edited);
}
DialogParticipantStatus DialogParticipantStatus::Member() {
return DialogParticipantStatus(Type::Member, IS_MEMBER | RestrictedRights::ALL_RESTRICTED_RIGHTS, 0, string());
}
DialogParticipantStatus DialogParticipantStatus::Restricted(
bool is_member, int32 restricted_until_date, bool can_send_messages, bool can_send_media, bool can_send_stickers,
bool can_send_animations, bool can_send_games, bool can_use_inline_bots, bool can_add_web_page_previews,
bool can_send_polls, bool can_change_info_and_settings, bool can_invite_users, bool can_pin_messages) {
uint32 flags = RestrictedRights(can_send_messages, can_send_media, can_send_stickers, can_send_animations,
can_send_games, can_use_inline_bots, can_add_web_page_previews, can_send_polls,
can_change_info_and_settings, can_invite_users, can_pin_messages)
.flags_ |
(static_cast<uint32>(is_member) * IS_MEMBER);
if (flags == (IS_MEMBER | RestrictedRights::ALL_RESTRICTED_RIGHTS)) {
return Member();
DialogParticipantStatus DialogParticipantStatus::Restricted(RestrictedRights restricted_rights, bool is_member,
int32 restricted_until_date) {
uint32 flags = restricted_rights.flags_;
if (flags == RestrictedRights::ALL_RESTRICTED_RIGHTS) {
return is_member ? Member() : Left();
}
flags |= (static_cast<uint32>(is_member) * IS_MEMBER);
return DialogParticipantStatus(Type::Restricted, flags, fix_until_date(restricted_until_date), string());
}
@ -321,14 +320,8 @@ DialogParticipantStatus::DialogParticipantStatus(bool can_be_edited,
tl_object_ptr<telegram_api::chatAdminRights> &&admin_rights,
string rank) {
CHECK(admin_rights != nullptr);
bool is_anonymous = admin_rights->anonymous_;
admin_rights->anonymous_ = false;
uint32 flags =
::td::get_administrator_rights(std::move(admin_rights)).flags_ | AdministratorRights::CAN_MANAGE_DIALOG;
if (is_anonymous) {
flags |= IS_ANONYMOUS;
}
if (can_be_edited) {
flags |= CAN_BE_EDITED;
}
@ -339,8 +332,7 @@ DialogParticipantStatus::DialogParticipantStatus(bool can_be_edited,
DialogParticipantStatus::DialogParticipantStatus(bool is_member,
tl_object_ptr<telegram_api::chatBannedRights> &&banned_rights) {
CHECK(banned_rights != nullptr);
bool can_view_messages = (banned_rights->flags_ & telegram_api::chatBannedRights::VIEW_MESSAGES_MASK) == 0;
if (!can_view_messages) {
if (banned_rights->view_messages_) {
*this = DialogParticipantStatus::Banned(banned_rights->until_date_);
return;
}
@ -383,7 +375,7 @@ tl_object_ptr<td_api::ChatMemberStatus> DialogParticipantStatus::get_chat_member
}
tl_object_ptr<telegram_api::chatAdminRights> DialogParticipantStatus::get_chat_admin_rights() const {
return get_administrator_rights().get_chat_admin_rights(is_anonymous());
return get_administrator_rights().get_chat_admin_rights();
}
tl_object_ptr<telegram_api::chatBannedRights> DialogParticipantStatus::get_chat_banned_rights() const {
@ -475,9 +467,6 @@ StringBuilder &operator<<(StringBuilder &string_builder, const DialogParticipant
if (!status.rank_.empty()) {
string_builder << " [" << status.rank_ << "]";
}
if (status.is_anonymous()) {
string_builder << "-anonymous";
}
return string_builder;
case DialogParticipantStatus::Type::Member:
return string_builder << "Member";
@ -518,7 +507,7 @@ DialogParticipantStatus get_dialog_participant_status(const tl_object_ptr<td_api
if (!clean_input_string(custom_title)) {
custom_title.clear();
}
return DialogParticipantStatus::Creator(st->is_member_, st->is_anonymous_, custom_title);
return DialogParticipantStatus::Creator(st->is_member_, st->is_anonymous_, std::move(custom_title));
}
case td_api::chatMemberStatusAdministrator::ID: {
auto st = static_cast<const td_api::chatMemberStatusAdministrator *>(status.get());
@ -526,30 +515,19 @@ DialogParticipantStatus get_dialog_participant_status(const tl_object_ptr<td_api
if (!clean_input_string(custom_title)) {
custom_title.clear();
}
return DialogParticipantStatus::Administrator(
st->is_anonymous_, custom_title, true /*st->can_be_edited_*/, st->can_manage_chat_, st->can_change_info_,
st->can_post_messages_, st->can_edit_messages_, st->can_delete_messages_, st->can_invite_users_,
st->can_restrict_members_, st->can_pin_messages_, st->can_promote_members_, st->can_manage_video_chats_);
AdministratorRights administrator_rights(st->is_anonymous_, st->can_manage_chat_, st->can_change_info_,
st->can_post_messages_, st->can_edit_messages_, st->can_delete_messages_,
st->can_invite_users_, st->can_restrict_members_, st->can_pin_messages_,
st->can_promote_members_, st->can_manage_video_chats_);
return DialogParticipantStatus::Administrator(administrator_rights, std::move(custom_title),
true /*st->can_be_edited_*/);
}
case td_api::chatMemberStatusMember::ID:
return DialogParticipantStatus::Member();
case td_api::chatMemberStatusRestricted::ID: {
auto st = static_cast<const td_api::chatMemberStatusRestricted *>(status.get());
auto permissions = st->permissions_.get();
if (permissions == nullptr) {
return DialogParticipantStatus::Restricted(st->is_member_, st->restricted_until_date_, false, false, false,
false, false, false, false, false, false, false, false);
}
bool can_send_polls = permissions->can_send_polls_;
bool can_send_media = permissions->can_send_media_messages_;
bool can_send_messages = permissions->can_send_messages_ || can_send_media || can_send_polls ||
permissions->can_send_other_messages_ || permissions->can_add_web_page_previews_;
return DialogParticipantStatus::Restricted(
st->is_member_, st->restricted_until_date_, can_send_messages, can_send_media,
permissions->can_send_other_messages_, permissions->can_send_other_messages_,
permissions->can_send_other_messages_, permissions->can_send_other_messages_,
permissions->can_add_web_page_previews_, permissions->can_send_polls_, permissions->can_change_info_,
permissions->can_invite_users_, permissions->can_pin_messages_);
return DialogParticipantStatus::Restricted(::td::get_restricted_rights(st->permissions_), st->is_member_,
st->restricted_until_date_);
}
case td_api::chatMemberStatusLeft::ID:
return DialogParticipantStatus::Left();
@ -565,58 +543,39 @@ DialogParticipantStatus get_dialog_participant_status(const tl_object_ptr<td_api
AdministratorRights get_administrator_rights(tl_object_ptr<telegram_api::chatAdminRights> &&admin_rights) {
if (admin_rights == nullptr) {
return AdministratorRights(false, false, false, false, false, false, false, false, false, false);
}
if (admin_rights->anonymous_) {
LOG(ERROR) << "Receive is_anonymous = true in AdministratorRights";
return AdministratorRights(false, false, false, false, false, false, false, false, false, false, false);
}
bool can_change_info = (admin_rights->flags_ & telegram_api::chatAdminRights::CHANGE_INFO_MASK) != 0;
bool can_post_messages = (admin_rights->flags_ & telegram_api::chatAdminRights::POST_MESSAGES_MASK) != 0;
bool can_edit_messages = (admin_rights->flags_ & telegram_api::chatAdminRights::EDIT_MESSAGES_MASK) != 0;
bool can_delete_messages = (admin_rights->flags_ & telegram_api::chatAdminRights::DELETE_MESSAGES_MASK) != 0;
bool can_invite_users = (admin_rights->flags_ & telegram_api::chatAdminRights::INVITE_USERS_MASK) != 0;
bool can_restrict_members = (admin_rights->flags_ & telegram_api::chatAdminRights::BAN_USERS_MASK) != 0;
bool can_pin_messages = (admin_rights->flags_ & telegram_api::chatAdminRights::PIN_MESSAGES_MASK) != 0;
bool can_promote_members = (admin_rights->flags_ & telegram_api::chatAdminRights::ADD_ADMINS_MASK) != 0;
bool can_manage_calls = (admin_rights->flags_ & telegram_api::chatAdminRights::MANAGE_CALL_MASK) != 0;
bool can_manage_dialog = (admin_rights->flags_ & telegram_api::chatAdminRights::OTHER_MASK) != 0;
if (!can_manage_dialog) {
if (!admin_rights->other_) {
LOG(ERROR) << "Receive wrong other flag in " << to_string(admin_rights);
}
return AdministratorRights(can_manage_dialog, can_change_info, can_post_messages, can_edit_messages,
can_delete_messages, can_invite_users, can_restrict_members, can_pin_messages,
can_promote_members, can_manage_calls);
return AdministratorRights(admin_rights->anonymous_, admin_rights->other_, admin_rights->change_info_,
admin_rights->post_messages_, admin_rights->edit_messages_, admin_rights->delete_messages_,
admin_rights->invite_users_, admin_rights->ban_users_, admin_rights->pin_messages_,
admin_rights->add_admins_, admin_rights->manage_call_);
}
RestrictedRights get_restricted_rights(tl_object_ptr<telegram_api::chatBannedRights> &&banned_rights) {
if (banned_rights == nullptr) {
return RestrictedRights(false, false, false, false, false, false, false, false, false, false, false);
}
bool can_view_messages = (banned_rights->flags_ & telegram_api::chatBannedRights::VIEW_MESSAGES_MASK) == 0;
if (!can_view_messages) {
LOG(ERROR) << "Can't view messages in restricted rights " << to_string(banned_rights);
if (banned_rights->view_messages_) {
LOG(ERROR) << "Can't view messages in banned rights " << to_string(banned_rights);
}
LOG_IF(ERROR, banned_rights->until_date_ != std::numeric_limits<int32>::max())
<< "Have until date " << banned_rights->until_date_ << " in restricted rights";
bool can_send_messages = (banned_rights->flags_ & telegram_api::chatBannedRights::SEND_MESSAGES_MASK) == 0;
bool can_send_media_messages = (banned_rights->flags_ & telegram_api::chatBannedRights::SEND_MEDIA_MASK) == 0;
bool can_send_stickers = (banned_rights->flags_ & telegram_api::chatBannedRights::SEND_STICKERS_MASK) == 0;
bool can_send_animations = (banned_rights->flags_ & telegram_api::chatBannedRights::SEND_GIFS_MASK) == 0;
bool can_send_games = (banned_rights->flags_ & telegram_api::chatBannedRights::SEND_GAMES_MASK) == 0;
bool can_use_inline_bots = (banned_rights->flags_ & telegram_api::chatBannedRights::SEND_INLINE_MASK) == 0;
bool can_add_web_page_previews = (banned_rights->flags_ & telegram_api::chatBannedRights::EMBED_LINKS_MASK) == 0;
bool can_send_polls = (banned_rights->flags_ & telegram_api::chatBannedRights::SEND_POLLS_MASK) == 0;
bool can_change_info_and_settings = (banned_rights->flags_ & telegram_api::chatBannedRights::CHANGE_INFO_MASK) == 0;
bool can_invite_users = (banned_rights->flags_ & telegram_api::chatBannedRights::INVITE_USERS_MASK) == 0;
bool can_pin_messages = (banned_rights->flags_ & telegram_api::chatBannedRights::PIN_MESSAGES_MASK) == 0;
return RestrictedRights(can_send_messages, can_send_media_messages, can_send_stickers, can_send_animations,
can_send_games, can_use_inline_bots, can_add_web_page_previews, can_send_polls,
can_change_info_and_settings, can_invite_users, can_pin_messages);
return RestrictedRights(!banned_rights->send_messages_, !banned_rights->send_media_, !banned_rights->send_stickers_,
!banned_rights->send_gifs_, !banned_rights->send_games_, !banned_rights->send_inline_,
!banned_rights->embed_links_, !banned_rights->send_polls_, !banned_rights->change_info_,
!banned_rights->invite_users_, !banned_rights->pin_messages_);
}
RestrictedRights get_restricted_rights(const td_api::object_ptr<td_api::chatPermissions> &permissions) {
if (permissions == nullptr) {
return RestrictedRights(false, false, false, false, false, false, false, false, false, false, false);
}
bool can_send_polls = permissions->can_send_polls_;
bool can_send_media = permissions->can_send_media_messages_;
bool can_send_messages = permissions->can_send_messages_ || can_send_media || can_send_polls ||
@ -624,7 +583,7 @@ RestrictedRights get_restricted_rights(const td_api::object_ptr<td_api::chatPerm
return RestrictedRights(can_send_messages, can_send_media, permissions->can_send_other_messages_,
permissions->can_send_other_messages_, permissions->can_send_other_messages_,
permissions->can_send_other_messages_, permissions->can_add_web_page_previews_,
permissions->can_send_polls_, permissions->can_change_info_, permissions->can_invite_users_,
can_send_polls, permissions->can_change_info_, permissions->can_invite_users_,
permissions->can_pin_messages_);
}

View File

@ -33,6 +33,7 @@ class AdministratorRights {
static constexpr uint32 CAN_PROMOTE_MEMBERS = 1 << 8;
static constexpr uint32 CAN_MANAGE_CALLS = 1 << 9;
static constexpr uint32 CAN_MANAGE_DIALOG = 1 << 10;
static constexpr uint32 IS_ANONYMOUS = 1 << 13;
static constexpr uint32 ALL_ADMINISTRATOR_RIGHTS =
CAN_CHANGE_INFO_AND_SETTINGS | CAN_POST_MESSAGES | CAN_EDIT_MESSAGES | CAN_DELETE_MESSAGES | CAN_INVITE_USERS |
@ -46,11 +47,12 @@ class AdministratorRights {
}
public:
AdministratorRights(bool can_manage_dialog, bool can_change_info, bool can_post_messages, bool can_edit_messages,
bool can_delete_messages, bool can_invite_users, bool can_restrict_members, bool can_pin_messages,
bool can_promote_members, bool can_manage_calls);
AdministratorRights(bool is_anonymous, bool can_manage_dialog, bool can_change_info, bool can_post_messages,
bool can_edit_messages, bool can_delete_messages, bool can_invite_users,
bool can_restrict_members, bool can_pin_messages, bool can_promote_members,
bool can_manage_calls);
telegram_api::object_ptr<telegram_api::chatAdminRights> get_chat_admin_rights(bool is_anonymous) const;
telegram_api::object_ptr<telegram_api::chatAdminRights> get_chat_admin_rights() const;
bool can_manage_dialog() const {
return (flags_ & CAN_MANAGE_DIALOG) != 0;
@ -97,6 +99,10 @@ class AdministratorRights {
return (flags_ & CAN_MANAGE_CALLS) != 0;
}
bool is_anonymous() const {
return (flags_ & IS_ANONYMOUS) != 0;
}
template <class StorerT>
void store(StorerT &storer) const {
td::store(flags_, storer);
@ -221,7 +227,6 @@ StringBuilder &operator<<(StringBuilder &string_builder, const RestrictedRights
class DialogParticipantStatus {
// only flags 11 and 12 are unused
static constexpr uint32 IS_ANONYMOUS = 1 << 13;
static constexpr uint32 HAS_RANK = 1 << 14;
static constexpr uint32 CAN_BE_EDITED = 1 << 15;
@ -251,9 +256,12 @@ class DialogParticipantStatus {
}
public:
static DialogParticipantStatus Creator(bool is_member, bool is_anonymous, string rank);
static DialogParticipantStatus Creator(bool is_member, bool is_anonymous, string &&rank);
static DialogParticipantStatus Administrator(bool is_anonymous, string rank, bool can_be_edited,
static DialogParticipantStatus Administrator(AdministratorRights administrator_rights, string &&rank,
bool can_be_edited);
static DialogParticipantStatus Administrator(bool is_anonymous, string &&rank, bool can_be_edited,
bool can_manage_dialog, bool can_change_info, bool can_post_messages,
bool can_edit_messages, bool can_delete_messages, bool can_invite_users,
bool can_restrict_members, bool can_pin_messages,
@ -261,12 +269,8 @@ class DialogParticipantStatus {
static DialogParticipantStatus Member();
static DialogParticipantStatus Restricted(bool is_member, int32 restricted_until_date, bool can_send_messages,
bool can_send_media, bool can_send_stickers, bool can_send_animations,
bool can_send_games, bool can_use_inline_bots,
bool can_add_web_page_previews, bool can_send_polls,
bool can_change_info_and_settings, bool can_invite_users,
bool can_pin_messages);
static DialogParticipantStatus Restricted(RestrictedRights restricted_rights, bool is_member,
int32 restricted_until_date);
static DialogParticipantStatus Left();
@ -414,7 +418,7 @@ class DialogParticipantStatus {
}
bool is_anonymous() const {
return (flags_ & IS_ANONYMOUS) != 0;
return get_administrator_rights().is_anonymous();
}
const string &get_rank() const {

View File

@ -430,6 +430,10 @@ class GetDiscussionMessageQuery final : public Td::ResultHandler {
if (expected_dialog_id_ == dialog_id_) {
td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "GetDiscussionMessageQuery");
}
if (status.message() == "MSG_ID_INVALID") {
td_->messages_manager_->get_message_from_server({dialog_id_, message_id_}, Promise<Unit>(),
"GetDiscussionMessageQuery");
}
promise_.set_error(std::move(status));
}
};
@ -10117,8 +10121,7 @@ void MessagesManager::on_get_history(DialogId dialog_id, MessageId from_message_
for (const auto &debug_message : messages) {
error += to_string(debug_message);
}
// TODO move to ERROR
LOG(FATAL) << error;
LOG(ERROR) << error;
promise.set_value(Unit());
return;
}
@ -10143,6 +10146,26 @@ void MessagesManager::on_get_history(DialogId dialog_id, MessageId from_message_
}
}
if (d->last_new_message_id.is_valid()) {
// remove too new messages from response
while (!messages.empty()) {
if (get_message_dialog_id(messages[0]) == dialog_id &&
get_message_id(messages[0], false) <= d->last_new_message_id) {
// the message is old enough
break;
}
LOG(INFO) << "Ignore too new " << get_message_id(messages[0], false);
messages.erase(messages.begin());
if (messages.empty()) {
// received no suitable messages; try again
return promise.set_value(Unit());
} else {
last_received_message_id = get_message_id(messages[0], false);
}
}
}
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;
@ -24161,8 +24184,7 @@ void MessagesManager::on_get_history_from_database(DialogId dialog_id, MessageId
break;
}
if (message->message_id >= last_received_message_id) {
// TODO move to ERROR
LOG(FATAL) << "Receive " << message->message_id << " after " << last_received_message_id
LOG(ERROR) << "Receive " << message->message_id << " after " << last_received_message_id
<< " from database in the history of " << dialog_id << " from " << from_message_id << " with offset "
<< offset << ", limit " << limit << ", from_the_end = " << from_the_end;
break;
@ -30580,7 +30602,7 @@ void MessagesManager::remove_message_dialog_notifications(Dialog *d, MessageId m
set_dialog_last_notification(d->dialog_id, group_info, 0, NotificationId(),
"remove_message_dialog_notifications 2");
} else {
LOG(FATAL) << "TODO support notification deletion up to " << max_message_id << " if will be ever needed";
LOG(FATAL) << "TODO support notification deletion up to " << max_message_id << " if it would be ever needed";
}
send_closure_later(G()->notification_manager(), &NotificationManager::remove_notification_group, group_info.group_id,
@ -38601,8 +38623,7 @@ void MessagesManager::on_get_channel_difference(
for (const auto &message : difference->new_messages_) {
auto message_id = get_message_id(message, false);
if (message_id <= cur_message_id) {
// TODO move to ERROR
LOG(FATAL) << "Receive " << cur_message_id << " after " << message_id << " in channelDifference of "
LOG(ERROR) << "Receive " << cur_message_id << " after " << message_id << " in channelDifference of "
<< dialog_id << " with pts " << request_pts << " and limit " << request_limit << ": "
<< to_string(difference);
after_get_channel_difference(dialog_id, false);

View File

@ -6233,7 +6233,8 @@ void Td::on_request(uint64 id, const td_api::leaveChat &request) {
return promise.set_value(Unit());
}
new_status = DialogParticipantStatus::Creator(false, status.is_anonymous(), status.get_rank());
auto rank = status.get_rank();
new_status = DialogParticipantStatus::Creator(false, status.is_anonymous(), std::move(rank));
}
}
contacts_manager_->set_dialog_participant_status(dialog_id, DialogId(contacts_manager_->get_my_id()),

View File

@ -302,8 +302,8 @@ void Scheduler::register_migrated_actor(ActorInfo *actor_info) {
VLOG(actor) << "Register migrated actor: " << tag("name", *actor_info) << tag("ptr", actor_info)
<< tag("actor_count", actor_count_);
actor_count_++;
LOG_CHECK(actor_info->is_migrating()) << *actor_info << " " << actor_count_ << " " << sched_id_ << " "
<< actor_info->migrate_dest() << " " << actor_info->is_running() << close_flag_;
LOG_CHECK(actor_info->is_migrating()) << *actor_info << ' ' << actor_count_ << ' ' << sched_id_ << ' '
<< actor_info->migrate_dest() << ' ' << actor_info->is_running() << ' ' << close_flag_;
CHECK(sched_id_ == actor_info->migrate_dest());
// CHECK(!actor_info->is_running());
actor_info->finish_migrate();

View File

@ -55,42 +55,57 @@
namespace td {
static uint64 gcd(uint64 a, uint64 b) {
static uint64 pq_gcd(uint64 a, uint64 b) {
if (a == 0) {
return b;
}
if (b == 0) {
return a;
}
int shift = 0;
while ((a & 1) == 0 && (b & 1) == 0) {
while ((a & 1) == 0) {
a >>= 1;
b >>= 1;
shift++;
}
DCHECK((b & 1) != 0);
while (true) {
while ((a & 1) == 0) {
a >>= 1;
}
while ((b & 1) == 0) {
b >>= 1;
}
if (a > b) {
a -= b;
a = (a - b) >> 1;
while ((a & 1) == 0) {
a >>= 1;
}
} else if (b > a) {
b -= a;
b = (b - a) >> 1;
while ((b & 1) == 0) {
b >>= 1;
}
} else {
return a << shift;
return a;
}
}
}
// returns (c + a * b) % pq
static uint64 pq_add_mul(uint64 c, uint64 a, uint64 b, uint64 pq) {
while (b) {
if (b & 1) {
c += a;
if (c >= pq) {
c -= pq;
}
}
a += a;
if (a >= pq) {
a -= pq;
}
b >>= 1;
}
return c;
}
uint64 pq_factorize(uint64 pq) {
if (pq < 2 || pq > (static_cast<uint64>(1) << 63)) {
if (pq <= 2 || pq > (static_cast<uint64>(1) << 63)) {
return 1;
}
if ((pq & 1) == 0) {
return 2;
}
uint64 g = 0;
for (int i = 0, iter = 0; i < 3 || iter < 1000; i++) {
uint64 q = Random::fast(17, 32) % (pq - 1);
@ -99,28 +114,9 @@ uint64 pq_factorize(uint64 pq) {
int lim = 1 << (min(5, i) + 18);
for (int j = 1; j < lim; j++) {
iter++;
uint64 a = x;
uint64 b = x;
uint64 c = q;
// c += a * b
while (b) {
if (b & 1) {
c += a;
if (c >= pq) {
c -= pq;
}
}
a += a;
if (a >= pq) {
a -= pq;
}
b >>= 1;
}
x = c;
x = pq_add_mul(q, x, x, pq);
uint64 z = x < y ? pq + x - y : x - y;
g = gcd(z, pq);
g = pq_gcd(z, pq);
if (g != 1) {
break;
}

View File

@ -14,11 +14,9 @@
#include "td/utils/logging.h"
#include "td/utils/SliceBuilder.h"
#include <algorithm>
#include <limits>
#include <utility>
#if TD_HAVE_OPENSSL
static bool is_prime(td::uint64 x) {
for (td::uint64 d = 2; d < x && d * d <= x; d++) {
if (x % d == 0) {
@ -28,9 +26,9 @@ static bool is_prime(td::uint64 x) {
return true;
}
static td::vector<td::uint64> gen_primes(td::uint64 L, td::uint64 R, int limit = 0) {
static td::vector<td::uint64> gen_primes(td::uint64 L, td::uint64 R, std::size_t limit = 0) {
td::vector<td::uint64> res;
for (auto x = L; x <= R && (limit <= 0 || res.size() < static_cast<std::size_t>(limit)); x++) {
for (auto x = L; x <= R && (limit <= 0 || res.size() < limit); x++) {
if (is_prime(x)) {
res.push_back(x);
}
@ -38,24 +36,26 @@ static td::vector<td::uint64> gen_primes(td::uint64 L, td::uint64 R, int limit =
return res;
}
static td::vector<td::uint64> gen_primes() {
static td::vector<td::uint64> gen_primes(int mode) {
td::vector<td::uint64> result;
td::append(result, gen_primes(1, 100));
td::append(result, gen_primes((1ull << 31) - 500000, std::numeric_limits<td::uint64>::max(), 5));
td::append(result, gen_primes((1ull << 32) - 500000, std::numeric_limits<td::uint64>::max(), 5));
td::append(result, gen_primes((1ull << 39) - 500000, std::numeric_limits<td::uint64>::max(), 1));
if (mode == 1) {
for (size_t i = 10; i <= 19; i++) {
td::append(result, gen_primes(i * 100000000, (i + 1) * 100000000, 1));
}
} else {
td::append(result, gen_primes(1, 100));
td::append(result, gen_primes((1ull << 31) - 500000, std::numeric_limits<td::uint64>::max(), 5));
td::append(result, gen_primes((1ull << 32) - 500000, std::numeric_limits<td::uint64>::max(), 2));
td::append(result, gen_primes((1ull << 39) - 500000, std::numeric_limits<td::uint64>::max(), 1));
}
return result;
}
using PqQuery = std::pair<td::uint64, td::uint64>;
static bool cmp(const PqQuery &a, const PqQuery &b) {
return a.first * a.second < b.first * b.second;
}
static td::vector<PqQuery> gen_pq_queries() {
static td::vector<PqQuery> gen_pq_queries(int mode = 0) {
td::vector<PqQuery> res;
auto primes = gen_primes();
auto primes = gen_primes(mode);
for (auto q : primes) {
for (auto p : primes) {
if (p > q) {
@ -64,11 +64,38 @@ static td::vector<PqQuery> gen_pq_queries() {
res.emplace_back(p, q);
}
}
std::sort(res.begin(), res.end(), cmp);
return res;
}
static void test_pq(td::uint64 first, td::uint64 second) {
static td::string to_binary(td::uint64 x) {
td::string result;
do {
result = static_cast<char>(x & 255) + result;
x >>= 8;
} while (x > 0);
return result;
}
static void test_pq_fast(td::uint64 first, td::uint64 second) {
if ((static_cast<td::uint64>(1) << 63) / first <= second) {
return;
}
td::string p_str;
td::string q_str;
int err = td::pq_factorize(to_binary(first * second), &p_str, &q_str);
ASSERT_EQ(err, 0);
ASSERT_STREQ(p_str, to_binary(first));
ASSERT_STREQ(q_str, to_binary(second));
}
#if TD_HAVE_OPENSSL
static void test_pq_slow(td::uint64 first, td::uint64 second) {
if ((static_cast<td::uint64>(1) << 63) / first > second) {
return;
}
td::BigNum p = td::BigNum::from_decimal(PSLICE() << first).move_as_ok();
td::BigNum q = td::BigNum::from_decimal(PSLICE() << second).move_as_ok();
@ -101,18 +128,35 @@ TEST(CryptoPQ, hands) {
ASSERT_EQ(179424611ull, td::pq_factorize(179424611ull * 179424673ull));
#if TD_HAVE_OPENSSL
test_pq(4294467311, 4294467449);
test_pq_slow(4294467311, 4294467449);
#endif
}
TEST(CryptoPQ, four) {
for (int i = 0; i < 100000; i++) {
test_pq_fast(2, 2);
}
}
TEST(CryptoPQ, generated_fast) {
auto queries = gen_pq_queries();
for (const auto &query : queries) {
test_pq_fast(query.first, query.second);
}
}
TEST(CryptoPQ, generated_server) {
auto queries = gen_pq_queries(1);
for (const auto &query : queries) {
test_pq_fast(query.first, query.second);
}
}
#if TD_HAVE_OPENSSL
TEST(CryptoPQ, generated_slow) {
for (int i = 0; i < 100000; i++) {
test_pq(2, 2);
}
auto queries = gen_pq_queries();
for (const auto &query : queries) {
test_pq(query.first, query.second);
test_pq_slow(query.first, query.second);
}
}
#endif