From 62d0bdbb77826bdbb9a778c56b8534d4b0c2c551 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Tue, 13 Oct 2020 00:14:28 +0200 Subject: Fix small typo in robustness logic --- src/Cache.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/Cache.cpp') diff --git a/src/Cache.cpp b/src/Cache.cpp index 088b6fc6..5a0740f1 100644 --- a/src/Cache.cpp +++ b/src/Cache.cpp @@ -1638,7 +1638,7 @@ Cache::getTimelineIndex(const std::string &room_id, std::string_view event_id) lmdb::dbi orderDb{0}; try { - orderDb = getOrderToMessageDb(txn, room_id); + orderDb = getMessageToOrderDb(txn, room_id); } catch (lmdb::runtime_error &e) { nhlog::db()->error("Can't open db for room '{}', probably doesn't exist yet. ({})", room_id, -- cgit 1.5.1 From aa9b453f8109b70c9e65fd21f2f3fcce0e73b544 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Tue, 20 Oct 2020 13:46:05 +0200 Subject: Store timestamp with olm sessions --- src/Cache.cpp | 145 +++++++++++++++++++++++++++++++++++++++-- src/Cache.h | 6 +- src/CacheCryptoStructs.h | 10 +++ src/Cache_p.h | 8 ++- src/Olm.cpp | 26 +++++--- src/Olm.h | 5 ++ src/timeline/EventStore.cpp | 6 ++ src/timeline/EventStore.h | 1 + src/timeline/TimelineModel.cpp | 3 +- 9 files changed, 191 insertions(+), 19 deletions(-) (limited to 'src/Cache.cpp') diff --git a/src/Cache.cpp b/src/Cache.cpp index 5a0740f1..d9db99b0 100644 --- a/src/Cache.cpp +++ b/src/Cache.cpp @@ -40,7 +40,7 @@ //! Should be changed when a breaking change occurs in the cache format. //! This will reset client's data. -static const std::string CURRENT_CACHE_FORMAT_VERSION("2020.07.05"); +static const std::string CURRENT_CACHE_FORMAT_VERSION("2020.10.20"); static const std::string SECRET("secret"); static lmdb::val NEXT_BATCH_KEY("next_batch"); @@ -437,7 +437,9 @@ Cache::getOutboundMegolmSession(const std::string &room_id) // void -Cache::saveOlmSession(const std::string &curve25519, mtx::crypto::OlmSessionPtr session) +Cache::saveOlmSession(const std::string &curve25519, + mtx::crypto::OlmSessionPtr session, + uint64_t timestamp) { using namespace mtx::crypto; @@ -447,7 +449,11 @@ Cache::saveOlmSession(const std::string &curve25519, mtx::crypto::OlmSessionPtr const auto pickled = pickle(session.get(), SECRET); const auto session_id = mtx::crypto::session_id(session.get()); - lmdb::dbi_put(txn, db, lmdb::val(session_id), lmdb::val(pickled)); + StoredOlmSession stored_session; + stored_session.pickled_session = pickled; + stored_session.last_message_ts = timestamp; + + lmdb::dbi_put(txn, db, lmdb::val(session_id), lmdb::val(json(stored_session).dump())); txn.commit(); } @@ -466,13 +472,44 @@ Cache::getOlmSession(const std::string &curve25519, const std::string &session_i txn.commit(); if (found) { - auto data = std::string(pickled.data(), pickled.size()); - return unpickle(data, SECRET); + std::string_view raw(pickled.data(), pickled.size()); + auto data = json::parse(raw).get(); + return unpickle(data.pickled_session, SECRET); } return std::nullopt; } +std::optional +Cache::getLatestOlmSession(const std::string &curve25519) +{ + using namespace mtx::crypto; + + auto txn = lmdb::txn::begin(env_); + auto db = getOlmSessionsDb(txn, curve25519); + + std::string session_id, pickled_session; + std::vector res; + + std::optional currentNewest; + + auto cursor = lmdb::cursor::open(txn, db); + while (cursor.get(session_id, pickled_session, MDB_NEXT)) { + auto data = + json::parse(std::string_view(pickled_session.data(), pickled_session.size())) + .get(); + if (!currentNewest || currentNewest->last_message_ts < data.last_message_ts) + currentNewest = data; + } + cursor.close(); + + txn.commit(); + + return currentNewest + ? std::optional(unpickle(currentNewest->pickled_session, SECRET)) + : std::nullopt; +} + std::vector Cache::getOlmSessions(const std::string &curve25519) { @@ -828,6 +865,80 @@ Cache::runMigrations() nhlog::db()->info("Successfully deleted pending receipts database."); return true; }}, + {"2020.10.20", + [this]() { + try { + using namespace mtx::crypto; + + auto txn = lmdb::txn::begin(env_); + + auto mainDb = lmdb::dbi::open(txn, nullptr); + + std::string dbName, ignored; + auto olmDbCursor = lmdb::cursor::open(txn, mainDb); + while (olmDbCursor.get(dbName, ignored, MDB_NEXT)) { + // skip every db but olm session dbs + nhlog::db()->debug("Db {}", dbName); + if (dbName.find("olm_sessions/") != 0) + continue; + + nhlog::db()->debug("Migrating {}", dbName); + + auto olmDb = lmdb::dbi::open(txn, dbName.c_str()); + + std::string session_id, session_value; + + std::vector> sessions; + + auto cursor = lmdb::cursor::open(txn, olmDb); + while (cursor.get(session_id, session_value, MDB_NEXT)) { + nhlog::db()->debug("session_id {}, session_value {}", + session_id, + session_value); + StoredOlmSession session; + bool invalid = false; + for (auto c : session_value) + if (!isprint(c)) { + invalid = true; + break; + } + if (invalid) + continue; + + nhlog::db()->debug("Not skipped"); + + session.pickled_session = session_value; + sessions.emplace_back(session_id, session); + } + cursor.close(); + + olmDb.drop(txn, true); + + auto newDbName = dbName; + newDbName.erase(0, sizeof("olm_sessions") - 1); + newDbName = "olm_sessions.v2" + newDbName; + + auto newDb = lmdb::dbi::open(txn, newDbName.c_str(), MDB_CREATE); + + for (const auto &[key, value] : sessions) { + nhlog::db()->debug("{}\n{}", key, json(value).dump()); + lmdb::dbi_put(txn, + newDb, + lmdb::val(key), + lmdb::val(json(value).dump())); + } + } + olmDbCursor.close(); + + txn.commit(); + } catch (const lmdb::error &) { + nhlog::db()->critical("Failed to migrate olm sessions,"); + return false; + } + + nhlog::db()->info("Successfully migrated olm sessions."); + return true; + }}, }; nhlog::db()->info("Running migrations, this may take a while!"); @@ -3629,6 +3740,19 @@ from_json(const nlohmann::json &obj, MegolmSessionIndex &msg) msg.sender_key = obj.at("sender_key"); } +void +to_json(nlohmann::json &obj, const StoredOlmSession &msg) +{ + obj["ts"] = msg.last_message_ts; + obj["s"] = msg.pickled_session; +} +void +from_json(const nlohmann::json &obj, StoredOlmSession &msg) +{ + msg.last_message_ts = obj.at("ts").get(); + msg.pickled_session = obj.at("s").get(); +} + namespace cache { void init(const QString &user_id) @@ -4114,9 +4238,11 @@ inboundMegolmSessionExists(const MegolmSessionIndex &index) // Olm Sessions // void -saveOlmSession(const std::string &curve25519, mtx::crypto::OlmSessionPtr session) +saveOlmSession(const std::string &curve25519, + mtx::crypto::OlmSessionPtr session, + uint64_t timestamp) { - instance_->saveOlmSession(curve25519, std::move(session)); + instance_->saveOlmSession(curve25519, std::move(session), timestamp); } std::vector getOlmSessions(const std::string &curve25519) @@ -4128,6 +4254,11 @@ getOlmSession(const std::string &curve25519, const std::string &session_id) { return instance_->getOlmSession(curve25519, session_id); } +std::optional +getLatestOlmSession(const std::string &curve25519) +{ + return instance_->getLatestOlmSession(curve25519); +} void saveOlmAccount(const std::string &pickled) diff --git a/src/Cache.h b/src/Cache.h index cd96708e..24b6df9e 100644 --- a/src/Cache.h +++ b/src/Cache.h @@ -292,11 +292,15 @@ inboundMegolmSessionExists(const MegolmSessionIndex &index); // Olm Sessions // void -saveOlmSession(const std::string &curve25519, mtx::crypto::OlmSessionPtr session); +saveOlmSession(const std::string &curve25519, + mtx::crypto::OlmSessionPtr session, + uint64_t timestamp); std::vector getOlmSessions(const std::string &curve25519); std::optional getOlmSession(const std::string &curve25519, const std::string &session_id); +std::optional +getLatestOlmSession(const std::string &curve25519); void saveOlmAccount(const std::string &pickled); diff --git a/src/CacheCryptoStructs.h b/src/CacheCryptoStructs.h index 935d6493..a693e233 100644 --- a/src/CacheCryptoStructs.h +++ b/src/CacheCryptoStructs.h @@ -66,6 +66,16 @@ struct OlmSessionStorage std::mutex group_inbound_mtx; }; +struct StoredOlmSession +{ + std::uint64_t last_message_ts = 0; + std::string pickled_session; +}; +void +to_json(nlohmann::json &obj, const StoredOlmSession &msg); +void +from_json(const nlohmann::json &obj, StoredOlmSession &msg); + //! Verification status of a single user struct VerificationStatus { diff --git a/src/Cache_p.h b/src/Cache_p.h index b3f4c58c..62b1ad37 100644 --- a/src/Cache_p.h +++ b/src/Cache_p.h @@ -266,10 +266,14 @@ public: // // Olm Sessions // - void saveOlmSession(const std::string &curve25519, mtx::crypto::OlmSessionPtr session); + void saveOlmSession(const std::string &curve25519, + mtx::crypto::OlmSessionPtr session, + uint64_t timestamp); std::vector getOlmSessions(const std::string &curve25519); std::optional getOlmSession(const std::string &curve25519, const std::string &session_id); + std::optional getLatestOlmSession( + const std::string &curve25519); void saveOlmAccount(const std::string &pickled); std::string restoreOlmAccount(); @@ -565,7 +569,7 @@ private: lmdb::dbi getOlmSessionsDb(lmdb::txn &txn, const std::string &curve25519_key) { return lmdb::dbi::open( - txn, std::string("olm_sessions/" + curve25519_key).c_str(), MDB_CREATE); + txn, std::string("olm_sessions.v2/" + curve25519_key).c_str(), MDB_CREATE); } QString getDisplayName(const mtx::events::StateEvent &event) diff --git a/src/Olm.cpp b/src/Olm.cpp index fee685a3..e3b0de27 100644 --- a/src/Olm.cpp +++ b/src/Olm.cpp @@ -47,7 +47,7 @@ handle_to_device_messages(const std::vectorwarn( @@ -56,10 +56,6 @@ handle_to_device_messages(const std::vectorwarn("validation error for olm message: {} {}", e.what(), j_msg.dump(2)); - - nhlog::crypto()->warn("validation error for olm message: {} {}", - e.what(), - j_msg.dump(2)); } } else if (msg_type == to_string(mtx::events::EventType::RoomKeyRequest)) { @@ -250,7 +246,8 @@ handle_pre_key_olm_message(const std::string &sender, nhlog::crypto()->debug("decrypted message: \n {}", plaintext.dump(2)); try { - cache::saveOlmSession(sender_key, std::move(inbound_session)); + cache::saveOlmSession( + sender_key, std::move(inbound_session), QDateTime::currentMSecsSinceEpoch()); } catch (const lmdb::error &e) { nhlog::db()->warn( "failed to save inbound olm session from {}: {}", sender, e.what()); @@ -318,7 +315,8 @@ try_olm_decryption(const std::string &sender_key, const mtx::events::msg::OlmCip try { text = olm::client()->decrypt_message(session->get(), msg.type, msg.body); - cache::saveOlmSession(id, std::move(session.value())); + cache::saveOlmSession( + id, std::move(session.value()), QDateTime::currentMSecsSinceEpoch()); } catch (const mtx::crypto::olm_exception &e) { nhlog::crypto()->debug("failed to decrypt olm message ({}, {}) with {}: {}", msg.type, @@ -672,7 +670,9 @@ send_megolm_key_to_device(const std::string &user_id, device_msg = olm::client()->create_olm_encrypted_content( olm_session.get(), json(room_key).dump(), pks.curve25519); - cache::saveOlmSession(pks.curve25519, std::move(olm_session)); + cache::saveOlmSession(pks.curve25519, + std::move(olm_session), + QDateTime::currentMSecsSinceEpoch()); } catch (const json::exception &e) { nhlog::crypto()->warn("creating outbound session: {}", e.what()); @@ -749,4 +749,14 @@ decryptEvent(const MegolmSessionIndex &index, return {std::nullopt, std::nullopt, std::move(te.data)}; } + +//! Send encrypted to device messages, targets is a map from userid to device ids or "*" +void +send_encrypted_to_device_messages(const std::map> targets, + const mtx::events::collections::DeviceEvents &event) +{ + (void)targets; + (void)event; +} + } // namespace olm diff --git a/src/Olm.h b/src/Olm.h index cda9f29a..2556a22d 100644 --- a/src/Olm.h +++ b/src/Olm.h @@ -110,4 +110,9 @@ send_megolm_key_to_device(const std::string &user_id, const std::string &device_id, const mtx::events::msg::ForwardedRoomKey &payload); +//! Send encrypted to device messages, targets is a map from userid to device ids or "*" +void +send_encrypted_to_device_messages(const std::map> targets, + const mtx::events::collections::DeviceEvents &event); + } // namespace olm diff --git a/src/timeline/EventStore.cpp b/src/timeline/EventStore.cpp index d3c5c3fa..3564ffc0 100644 --- a/src/timeline/EventStore.cpp +++ b/src/timeline/EventStore.cpp @@ -54,6 +54,9 @@ EventStore::EventStore(std::string room_id, QObject *) &EventStore::oldMessagesRetrieved, this, [this](const mtx::responses::Messages &res) { + if (cache::client()->previousBatchToken(room_id_) == res.end) + noMoreMessages = true; + uint64_t newFirst = cache::client()->saveOldMessages(room_id_, res); if (newFirst == first) fetchMore(); @@ -687,6 +690,9 @@ EventStore::get(std::string_view id, std::string_view related_to, bool decrypt) void EventStore::fetchMore() { + if (noMoreMessages) + return; + mtx::http::MessagesOpts opts; opts.room_id = room_id_; opts.from = cache::client()->previousBatchToken(room_id_); diff --git a/src/timeline/EventStore.h b/src/timeline/EventStore.h index 954e271c..7f8e2396 100644 --- a/src/timeline/EventStore.h +++ b/src/timeline/EventStore.h @@ -123,4 +123,5 @@ private: std::string current_txn; int current_txn_error_count = 0; + bool noMoreMessages = false; }; diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp index 359e95bc..5db6aa00 100644 --- a/src/timeline/TimelineModel.cpp +++ b/src/timeline/TimelineModel.cpp @@ -1138,7 +1138,8 @@ TimelineModel::handleClaimedKeys( pks.at(user_id).at(device_id).curve25519); try { - cache::saveOlmSession(id_key, std::move(s)); + cache::saveOlmSession( + id_key, std::move(s), QDateTime::currentMSecsSinceEpoch()); } catch (const lmdb::error &e) { nhlog::db()->critical("failed to save outbound olm session: {}", e.what()); -- cgit 1.5.1 From 66445c507c4ea9322c91306e7ee0d145b8dbd94d Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Thu, 22 Oct 2020 20:48:28 +0200 Subject: Trade CPU usage for 30MB of members in RAM --- src/Cache.cpp | 115 +++++++++--------------------------------------- src/Cache.h | 13 ------ src/Cache_p.h | 36 +++------------ src/ChatPage.cpp | 2 - src/Olm.cpp | 4 +- src/TextInputWidget.cpp | 4 +- src/Utils.cpp | 2 +- 7 files changed, 30 insertions(+), 146 deletions(-) (limited to 'src/Cache.cpp') diff --git a/src/Cache.cpp b/src/Cache.cpp index d9db99b0..090af913 100644 --- a/src/Cache.cpp +++ b/src/Cache.cpp @@ -2280,34 +2280,22 @@ Cache::joinedRooms() return room_ids; } -void -Cache::populateMembers() +std::optional +Cache::getMember(const std::string &room_id, const std::string &user_id) { - auto rooms = joinedRooms(); - nhlog::db()->info("loading {} rooms", rooms.size()); - - auto txn = lmdb::txn::begin(env_); - - for (const auto &room : rooms) { - const auto roomid = QString::fromStdString(room); - - auto membersdb = getMembersDb(txn, room); - auto cursor = lmdb::cursor::open(txn, membersdb); - - std::string user_id, info; - while (cursor.get(user_id, info, MDB_NEXT)) { - MemberInfo m = json::parse(info); + try { + auto txn = lmdb::txn::begin(env_); - const auto userid = QString::fromStdString(user_id); + auto membersdb = getMembersDb(txn, room_id); - insertDisplayName(roomid, userid, QString::fromStdString(m.name)); - insertAvatarUrl(roomid, userid, QString::fromStdString(m.avatar_url)); + lmdb::val info; + if (lmdb::dbi_get(txn, membersdb, lmdb::val(user_id), info)) { + MemberInfo m = json::parse(std::string_view(info.data(), info.size())); + return m; } - - cursor.close(); + } catch (...) { } - - txn.commit(); + return std::nullopt; } std::vector @@ -3145,15 +3133,12 @@ Cache::roomMembers(const std::string &room_id) return members; } -QHash Cache::DisplayNames; -QHash Cache::AvatarUrls; - QString Cache::displayName(const QString &room_id, const QString &user_id) { - auto fmt = QString("%1 %2").arg(room_id).arg(user_id); - if (DisplayNames.contains(fmt)) - return DisplayNames[fmt]; + if (auto info = getMember(room_id.toStdString(), user_id.toStdString()); + info && !info->name.empty()) + return QString::fromStdString(info->name); return user_id; } @@ -3161,9 +3146,8 @@ Cache::displayName(const QString &room_id, const QString &user_id) std::string Cache::displayName(const std::string &room_id, const std::string &user_id) { - auto fmt = QString::fromStdString(room_id + " " + user_id); - if (DisplayNames.contains(fmt)) - return DisplayNames[fmt].toStdString(); + if (auto info = getMember(room_id, user_id); info && !info->name.empty()) + return info->name; return user_id; } @@ -3171,41 +3155,11 @@ Cache::displayName(const std::string &room_id, const std::string &user_id) QString Cache::avatarUrl(const QString &room_id, const QString &user_id) { - auto fmt = QString("%1 %2").arg(room_id).arg(user_id); - if (AvatarUrls.contains(fmt)) - return AvatarUrls[fmt]; + if (auto info = getMember(room_id.toStdString(), user_id.toStdString()); + info && !info->avatar_url.empty()) + return QString::fromStdString(info->avatar_url); - return QString(); -} - -void -Cache::insertDisplayName(const QString &room_id, - const QString &user_id, - const QString &display_name) -{ - auto fmt = QString("%1 %2").arg(room_id).arg(user_id); - DisplayNames.insert(fmt, display_name); -} - -void -Cache::removeDisplayName(const QString &room_id, const QString &user_id) -{ - auto fmt = QString("%1 %2").arg(room_id).arg(user_id); - DisplayNames.remove(fmt); -} - -void -Cache::insertAvatarUrl(const QString &room_id, const QString &user_id, const QString &avatar_url) -{ - auto fmt = QString("%1 %2").arg(room_id).arg(user_id); - AvatarUrls.insert(fmt, avatar_url); -} - -void -Cache::removeAvatarUrl(const QString &room_id, const QString &user_id) -{ - auto fmt = QString("%1 %2").arg(room_id).arg(user_id); - AvatarUrls.remove(fmt); + return ""; } mtx::presence::PresenceState @@ -3793,28 +3747,6 @@ avatarUrl(const QString &room_id, const QString &user_id) return instance_->avatarUrl(room_id, user_id); } -void -removeDisplayName(const QString &room_id, const QString &user_id) -{ - instance_->removeDisplayName(room_id, user_id); -} -void -removeAvatarUrl(const QString &room_id, const QString &user_id) -{ - instance_->removeAvatarUrl(room_id, user_id); -} - -void -insertDisplayName(const QString &room_id, const QString &user_id, const QString &display_name) -{ - instance_->insertDisplayName(room_id, user_id, display_name); -} -void -insertAvatarUrl(const QString &room_id, const QString &user_id, const QString &avatar_url) -{ - instance_->insertAvatarUrl(room_id, user_id, avatar_url); -} - mtx::presence::PresenceState presenceState(const std::string &user_id) { @@ -3826,13 +3758,6 @@ statusMessage(const std::string &user_id) return instance_->statusMessage(user_id); } -//! Load saved data for the display names & avatars. -void -populateMembers() -{ - instance_->populateMembers(); -} - // user cache stores user keys std::optional userKeys(const std::string &user_id) diff --git a/src/Cache.h b/src/Cache.h index 24b6df9e..98e6cb75 100644 --- a/src/Cache.h +++ b/src/Cache.h @@ -44,16 +44,6 @@ displayName(const QString &room_id, const QString &user_id); QString avatarUrl(const QString &room_id, const QString &user_id); -void -removeDisplayName(const QString &room_id, const QString &user_id); -void -removeAvatarUrl(const QString &room_id, const QString &user_id); - -void -insertDisplayName(const QString &room_id, const QString &user_id, const QString &display_name); -void -insertAvatarUrl(const QString &room_id, const QString &user_id, const QString &avatar_url); - // presence mtx::presence::PresenceState presenceState(const std::string &user_id); @@ -74,9 +64,6 @@ markDeviceVerified(const std::string &user_id, const std::string &device); void markDeviceUnverified(const std::string &user_id, const std::string &device); -//! Load saved data for the display names & avatars. -void -populateMembers(); std::vector joinedRooms(); diff --git a/src/Cache_p.h b/src/Cache_p.h index 62b1ad37..a32793ea 100644 --- a/src/Cache_p.h +++ b/src/Cache_p.h @@ -46,9 +46,9 @@ class Cache : public QObject public: Cache(const QString &userId, QObject *parent = nullptr); - static std::string displayName(const std::string &room_id, const std::string &user_id); - static QString displayName(const QString &room_id, const QString &user_id); - static QString avatarUrl(const QString &room_id, const QString &user_id); + std::string displayName(const std::string &room_id, const std::string &user_id); + QString displayName(const QString &room_id, const QString &user_id); + QString avatarUrl(const QString &room_id, const QString &user_id); // presence mtx::presence::PresenceState presenceState(const std::string &user_id); @@ -71,18 +71,6 @@ public: void markDeviceVerified(const std::string &user_id, const std::string &device); void markDeviceUnverified(const std::string &user_id, const std::string &device); - static void removeDisplayName(const QString &room_id, const QString &user_id); - static void removeAvatarUrl(const QString &room_id, const QString &user_id); - - static void insertDisplayName(const QString &room_id, - const QString &user_id, - const QString &display_name); - static void insertAvatarUrl(const QString &room_id, - const QString &user_id, - const QString &avatar_url); - - //! Load saved data for the display names & avatars. - void populateMembers(); std::vector joinedRooms(); QMap roomInfo(bool withInvites = true); @@ -308,6 +296,8 @@ private: QString getInviteRoomTopic(lmdb::txn &txn, lmdb::dbi &statesdb); QString getInviteRoomAvatarUrl(lmdb::txn &txn, lmdb::dbi &statesdb, lmdb::dbi &membersdb); + std::optional getMember(const std::string &room_id, const std::string &user_id); + std::string getLastEventId(lmdb::txn &txn, const std::string &room_id); DescInfo getLastMessageInfo(lmdb::txn &txn, const std::string &room_id); void saveTimelineMessages(lmdb::txn &txn, @@ -364,25 +354,12 @@ private: lmdb::val(e->state_key), lmdb::val(json(tmp).dump())); - insertDisplayName(QString::fromStdString(room_id), - QString::fromStdString(e->state_key), - QString::fromStdString(display_name)); - - insertAvatarUrl(QString::fromStdString(room_id), - QString::fromStdString(e->state_key), - QString::fromStdString(e->content.avatar_url)); - break; } default: { lmdb::dbi_del( txn, membersdb, lmdb::val(e->state_key), lmdb::val("")); - removeDisplayName(QString::fromStdString(room_id), - QString::fromStdString(e->state_key)); - removeAvatarUrl(QString::fromStdString(room_id), - QString::fromStdString(e->state_key)); - break; } } @@ -602,9 +579,6 @@ private: QString localUserId_; QString cacheDirectory_; - static QHash DisplayNames; - static QHash AvatarUrls; - OlmSessionStorage session_storage; VerificationStorage verification_storage; }; diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp index 8b6f1123..103905d1 100644 --- a/src/ChatPage.cpp +++ b/src/ChatPage.cpp @@ -774,8 +774,6 @@ ChatPage::loadStateFromCache() cache::restoreSessions(); olm::client()->load(cache::restoreOlmAccount(), STORAGE_SECRET_KEY); - cache::populateMembers(); - emit initializeEmptyViews(cache::roomMessages()); emit initializeRoomList(cache::roomInfo()); emit initializeMentions(cache::getTimelineMentions()); diff --git a/src/Olm.cpp b/src/Olm.cpp index d6e8c10b..8cc9bed8 100644 --- a/src/Olm.cpp +++ b/src/Olm.cpp @@ -417,8 +417,8 @@ send_key_request_for(mtx::events::EncryptedEvent e, e.content.session_id); mtx::events::msg::KeyRequest request; - request.action = !cancel ? mtx::events::msg::RequestAction::Request - : mtx::events::msg::RequestAction::Cancellation; + request.action = !cancel ? mtx::events::msg::RequestAction::Request + : mtx::events::msg::RequestAction::Cancellation; request.algorithm = MEGOLM_ALGO; request.room_id = e.room_id; request.sender_key = e.content.sender_key; diff --git a/src/TextInputWidget.cpp b/src/TextInputWidget.cpp index 22e8aafc..37a65f9e 100644 --- a/src/TextInputWidget.cpp +++ b/src/TextInputWidget.cpp @@ -450,8 +450,8 @@ FilteredTextEdit::completerRect() auto item_height = completer_->popup()->sizeHintForRow(0); auto max_height = item_height * completer_->maxVisibleItems(); auto height = (completer_->completionCount() > completer_->maxVisibleItems()) - ? max_height - : completer_->completionCount() * item_height; + ? max_height + : completer_->completionCount() * item_height; rect.setWidth(completer_->popup()->sizeHintForColumn(0)); rect.moveBottom(-height); return rect; diff --git a/src/Utils.cpp b/src/Utils.cpp index 0bfc82c3..38dbba22 100644 --- a/src/Utils.cpp +++ b/src/Utils.cpp @@ -638,7 +638,7 @@ utils::luminance(const QColor &col) qreal lumRgb[3]; for (int i = 0; i < 3; i++) { - qreal v = colRgb[i] / 255.0; + qreal v = colRgb[i] / 255.0; v <= 0.03928 ? lumRgb[i] = v / 12.92 : lumRgb[i] = qPow((v + 0.055) / 1.055, 2.4); } -- cgit 1.5.1 From 4797b9fa9651c2bb5a35ca67497c2f0eb4956820 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Fri, 23 Oct 2020 19:42:12 +0200 Subject: Fix infinite pagination properly now. --- src/Cache.cpp | 13 ++++++++++++- src/TextInputWidget.cpp | 4 ++-- src/Utils.cpp | 2 +- src/timeline/EventStore.cpp | 5 ++++- 4 files changed, 19 insertions(+), 5 deletions(-) (limited to 'src/Cache.cpp') diff --git a/src/Cache.cpp b/src/Cache.cpp index 090af913..3ffa9fd2 100644 --- a/src/Cache.cpp +++ b/src/Cache.cpp @@ -2712,8 +2712,19 @@ Cache::saveOldMessages(const std::string &room_id, const mtx::responses::Message } } - if (res.chunk.empty()) + if (res.chunk.empty()) { + if (lmdb::dbi_get(txn, orderDb, lmdb::val(&index, sizeof(index)), val)) { + auto orderEntry = json::parse(std::string_view(val.data(), val.size())); + orderEntry["prev_batch"] = res.end; + lmdb::dbi_put(txn, + orderDb, + lmdb::val(&index, sizeof(index)), + lmdb::val(orderEntry.dump())); + nhlog::db()->debug("saving '{}'", orderEntry.dump()); + txn.commit(); + } return index; + } std::string event_id_val; for (const auto &e : res.chunk) { diff --git a/src/TextInputWidget.cpp b/src/TextInputWidget.cpp index 37a65f9e..22e8aafc 100644 --- a/src/TextInputWidget.cpp +++ b/src/TextInputWidget.cpp @@ -450,8 +450,8 @@ FilteredTextEdit::completerRect() auto item_height = completer_->popup()->sizeHintForRow(0); auto max_height = item_height * completer_->maxVisibleItems(); auto height = (completer_->completionCount() > completer_->maxVisibleItems()) - ? max_height - : completer_->completionCount() * item_height; + ? max_height + : completer_->completionCount() * item_height; rect.setWidth(completer_->popup()->sizeHintForColumn(0)); rect.moveBottom(-height); return rect; diff --git a/src/Utils.cpp b/src/Utils.cpp index 38dbba22..0bfc82c3 100644 --- a/src/Utils.cpp +++ b/src/Utils.cpp @@ -638,7 +638,7 @@ utils::luminance(const QColor &col) qreal lumRgb[3]; for (int i = 0; i < 3; i++) { - qreal v = colRgb[i] / 255.0; + qreal v = colRgb[i] / 255.0; v <= 0.03928 ? lumRgb[i] = v / 12.92 : lumRgb[i] = qPow((v + 0.055) / 1.055, 2.4); } diff --git a/src/timeline/EventStore.cpp b/src/timeline/EventStore.cpp index 22809a20..38292f49 100644 --- a/src/timeline/EventStore.cpp +++ b/src/timeline/EventStore.cpp @@ -54,8 +54,11 @@ EventStore::EventStore(std::string room_id, QObject *) &EventStore::oldMessagesRetrieved, this, [this](const mtx::responses::Messages &res) { - if (cache::client()->previousBatchToken(room_id_) == res.end) + if (cache::client()->previousBatchToken(room_id_) == res.end) { noMoreMessages = true; + emit fetchedMore(); + return; + } uint64_t newFirst = cache::client()->saveOldMessages(room_id_, res); if (newFirst == first) -- cgit 1.5.1 From 3d7bb22df4a408ab837710f2e44810df975a667c Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Sat, 24 Oct 2020 18:07:14 +0200 Subject: Fix login --- src/Cache.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/Cache.cpp') diff --git a/src/Cache.cpp b/src/Cache.cpp index 3ffa9fd2..993fbfe7 100644 --- a/src/Cache.cpp +++ b/src/Cache.cpp @@ -2284,7 +2284,7 @@ std::optional Cache::getMember(const std::string &room_id, const std::string &user_id) { try { - auto txn = lmdb::txn::begin(env_); + auto txn = lmdb::txn::begin(env_, nullptr, MDB_RDONLY); auto membersdb = getMembersDb(txn, room_id); -- cgit 1.5.1