aboutsummaryrefslogtreecommitdiff
AgeCommit message (Collapse)Author
2022-07-29Moving eventCast()Alexey Rusakov
In a situation where you have an EventPtr that you want to place somewhere as an `event_ptr_tt<SomeMoreSpecificEventType>` you have to carefully check that the stored event is actually of SomeMoreSpecificType and if it is, release() that event pointer, downcast, and re-wrap it into that new event_ptr_tt - or, as can be seen from the diff here, re-loadEvent() from JSON, which is simpler but inefficient. To help clients, and the library, eventCast() can now accept an rvalue smart pointer and do all the necessary things with it.
2022-07-26...and the definitive fixAlexey Rusakov
2022-07-26Another fix attemptAlexey Rusakov
2022-07-26Hopefully fix building with GCCAlexey Rusakov
The last commit broke it.
2022-07-26Add missing QUOTIENT_API piecesAlexey Rusakov
The upcoming event type infrastructure finally helps to detect those omissions more or less reliably (for event types only though).
2022-07-25Fix accidentally logging all receipt authorsAlexey Rusakov
...instead of just the number of them.
2022-07-25Don't redact certain event types even though lib doesn't know themAlexey Rusakov
Event type ids don't need a C++ type to be used, and clients might define those types on their side (NeoChat does that, e.g.).
2022-07-16Speed up read receipt updatesAlexey Rusakov
Profiling revealed 3 inefficiencies in read receipts code - and given there are a lot of them coming, these inefficiences quickly add up. Fixing them allows to slash read receipt processing time by 60%, and the total time of updating a room by more than a half. 1. Room::lastReadEventChanged() is emitted per receipt. This can be taxing on initial syncs or in bigger rooms; this commit converts it to an aggregate signal only emitted once per sync room batch and carrying the list of all user ids (more on that below) with updated read receipts. For that, Room::P::setLastReadEvent() is split into Room::P::setLocalLastReadEvent() that is called whenever the local read receipt has to be updated, and setLastReadEvent() proper that is very fast and only updates the internal data structures, nothing else. setLocalLastEvent() calls it, as does processEphemeralEvents(); both take responsibility to emit lastReadEventChanged() depending on the outcome of setLastReadEvent() invocation(s). 2. Massively aggravating the above point, user id from each read receipt is turned to a User object - and since most of the users are unknown at early moments, this causes thousands of allocations. Therefore the new aggregated lastReadEventChanged() only carries user ids, and clients will have to resolve them to User objects if they need. 3. Despite fairly tight conditions (note we're talking about thousands of receipts), Quotient still creates an intermediate C++ structure (EventsWithReceipts), only for the sake of passing it to processEphemeralEvent() that immediately disassembles it back again, converting to a series of calls to set(Local)LastReadEvent(). To fix this, processEphemeralEvent() now takes the event content JSON directly and iterates over it instead. Aside from that, a few extraneous conditions and logging has been removed and the whole function rewritten with switchOnType() to reduce cognitive complexity.
2022-07-16Room::decryptIncomingEvents()Alexey Rusakov
The result of factoring out duplicate code.
2022-07-16logging.h: suppress clang-tidy warningsAlexey Rusakov
2022-07-15Connection::user(): validate after lookup, not beforeAlexey Rusakov
If userMap only holds valid ids, there's no reason to spend time validating the sought id: if it's invalid, it won't be found. And lookups over a hash map are cheap.
2022-07-15operator<<(QDebug, QElapsedTimer): always use msAlexey Rusakov
That switch between micro- and milliseconds was pure visual sugaring, in a potentially time-sensitive context. Also: there's no sense in using const-ref for a small parameter in a function that is, to top it off, almost always inlined.
2022-07-15Bring back documentation on PROFILE_LOG_USECSAlexey Rusakov
I was about to decommission it but got to use it myself. [skip ci]
2022-07-13eventcontent.h: Use C++17 nested namespaces notationAlexey Rusakov
2022-07-12Merge branch 'kitsune/converters-upgrade' into devAlexey Rusakov
2022-07-12converters.*: facilities to convert enumsAlexey Rusakov
This introduces enumTo/FromJsonString() and flagTo/FromJsonString(), four facility functions to simplify conversion between C++ enums and JSON, and refactors a couple of places where it's useful.
2022-07-12Make AliasesEventContent a simple structureAlexey Rusakov
JSON conversions are moved out of the class, obviating the need to define the plain data constructor and gaining default-constructibility along the way - previously the default constructor was preempted by user-defined ones.
2022-07-12Refactor things around EncryptionEvent[Content]Alexey Rusakov
EncryptionEvent was marked as Q_GADGET only for the sake of defining EncryptionType inside of it as Q_ENUM, with aliases also available under Quotient:: and EncryptionEventContent. This is a legacy from pre-Q_ENUM_NS times. However, event types are not really made to be proper Q_GADGETs: Q_GADGET implies access by value or reference but event types are uncopyable for the former and QML is ill-equipped for the latter. This commit moves EncryptionType definition to where other such enumerations reside - on the namespace level in quotient_common.h; and the other two places are now deprecated; and EncryptionEvent is no more Q_GADGET. With fromJson/toJson refactored in the previous commit there's no more need to specialise JsonConverter<>: specialising fromJson() is just enough. Moving EncryptionType to quotient_common.h exposed the clash of two Undefined enumerators (in RoomType and EncryptionType), warranting both enumerations to become scoped (which they ought to be, anyway). And while we're at it, the base type of enumerations is specified explicitly, as MSVC apparently uses a signed base type (int?) by default, unlike other compilers, and the upcoming enum converters will assume an unsigned base type. Finally, using fillFromJson() instead of fromJson() in the EncryptionEventContent constructor allowed to make default values explicit in the header file, rather than buried in the initialisation code.
2022-07-12fromJson()/toJson() refactoringAlexey Rusakov
fromJson() is generalised to accept any JSON-like type while passing QJsonObject to JsonConverter<>::load (instead of doLoad). This allows to (still) rely on JsonConverter<> as a customisation point while providing an opportunity to overload fromJson for custom types in a pointed way (specifically, by providing the overload for `fromJson(const QJsonObject&)`), instead of having to go with full-blown JsonConverter<> specialisation. This will be used in a further commit to simplify ReceiptEvent definition. Using if constexpr in combination with constraints (`requires()`) - the first such case in Quotient codebase - allowed to put the entire logic in a single JsonConverter<>::load() body instead of having a facility JsonExporter<> class for SFINAE. Aside from that, fromJson<QJsonValue, QJsonValue> is entirely dropped because it's not supposed to be used that way (it's no-op after all); reflecting that, Event::unsignedPart() and Event::contentPart() no more default to QJsonValue as the expected return type, you have to explicitly provide the type instead (and as one can see from the changes in the commit, it's actually better that way since it's better to validate the value inside JSON - e.g. check QString or QJsonObject for emptiness - than the QJsonValue envelope which may still wrap an empty value). toJson() is also generalised, replacing 3 functions with one that has a constexpr if to discern between two kinds of types.
2022-07-12Fix deprecation messagesAlexey Rusakov
[skip ci]
2022-07-12Pack up StickerEvent in the header fileAlexey Rusakov
Dropping yet another translation unit.
2022-07-11Reuse Room::setState() overloads from one anotherAlexey Rusakov
2022-07-11Small .clang-format adjustmentsAlexey Rusakov
2022-07-11Add QUOTIENT_API to RoomStateViewAlexey Rusakov
Fixing link errors at non-template RoomStateView::get() when building with libQuotient as a shared object. There's also a test in quotest.cpp now to cover that case.
2022-07-08qt_connection_util.h: use autoAlexey Rusakov
2022-07-08clang-format: don't break lines before lambda bodyAlexey Rusakov
Aside from breaking that line, the previous line - with connect*() - is often broken up too, making smaller lambdas consume much more vertical space.
2022-07-08Use clang-format 12; update CONTRIBUTING.md wrt code formattingAlexey Rusakov
[skip ci]
2022-07-08Merge remote-tracking branch 'origin/kitsune/c++20-galore' into devAlexey Rusakov
2022-07-08Adjust Synapse image for testsAlexey Rusakov
:latest stopped working for some reason.
2022-07-08CI: use GCC 11 and (therefore) ubuntu-22.04Alexey Rusakov
GCC 10 ICE's[1] in qt_connection_util.h code; and ubuntu-20.04 doesn't have GCC 11. Also: patch a Qt 5.15 header when compiling with GCC because a combination of Qt 5.15 and GCC 11 in turn triggers QTBUG-91909/90568... Which in turn required moving Qt setup before the build environment setup. Life's fun. [1] Internal Compiler Error
2022-07-07Avoid std::derived_from and std::bind_frontAlexey Rusakov
Apple Clang doesn't have those yet.
2022-07-03Shorten switchOnType, function_traits and connect*Alexey Rusakov
...thanks to C++20 awesomeness. A notable change is that wrap_in_function() (and respectively function_traits<>::function_type) and fn_return_t alias are gone. The former are no more needed because connectUntil/connectSingleShot no more use std::function. The latter has been relatively underused and with the optimisation of switchOnType hereby, could be completely replaced with std::invoke_result_t. Rewriting connect* functions using constexpr and auto parameters made the implementation 30% more compact and much easier to understand (though still with a couple of - now thoroughly commented - tricky places). Dropping std::function<> from it may also bring some (quite modest, likely) performance benefits.
2022-06-24Make EventContent::Base() move constructor noexceptAlexey Rusakov
2022-06-24Fix the just introduced Sonar warningAlexey Rusakov
Too many parameters of the same type in a row.
2022-06-24Start using C++20's designated initializersAlexey Rusakov
2022-06-24Code cleanup and reformattingAlexey Rusakov
2022-06-24Rework SignedOneTimeKey as a QJsonObject wrapperAlexey Rusakov
Since this object has to be verified against a signature it also carries there's a rather specific procedure described in The Spec for that. That procedure basically assumes handling the signed one-time key object as a JSON object, not as a C++ object. And originally Quotient E2EE code was exactly like that (obtaining the right QJsonObject from the job result and handling it as specced) but then one enthusiastic developer (me) decided it's better to use a proper C++ structure - breaking the verification logic along the way. After a couple attempts to fix it, here we are again: SignedOneTimeKey is a proper QJsonObject, and even provides a method returning its JSON in the form prepared for verification (according to the spec).
2022-06-24Fix copy-pasta in signed one-time key JSON dumperAlexey Rusakov
2022-06-23Streamline Room::P::shouldRotateMegolmSession()Alexey Rusakov
Now there's only 1 instead of 5 lookups of the same EncryptionEvent, and the code is shorter.
2022-06-23Use QUO_CONTENT_GETTERAlexey Rusakov
In keyverificationevent.*, this massively shortens repetitive getter definitions; the remaining few non-trivial ones are moved to keyverificationevent.h, dropping the respective .cpp file and therefore the dedicated translation unit. In roomkeyevent.h, it's just shorter.
2022-06-23Drop QUOTIENT_API where it's undueAlexey Rusakov
2022-06-22Fix signature verificationAlexey Rusakov
toJson(SignedOneTimeKey) incorrectly generated a "signatures" key mapped to an empty object when no signatures were in the C++ value. Also: fallback keys have an additional flag that also has to be taken into account when verifying signatures.
2022-06-22.clang-tidy: drop another rather useless warningAlexey Rusakov
'performance-no-automatic-move' triggers on code where copy elision normally takes place anyway. In fact, all cases it triggered on were also subject to named return value optimisation (NRVO). [skip ci]
2022-06-22RoomSummary::merge(): explicitly cast between int and boolAlexey Rusakov
Honestly, it was quite intuitive even without that, but in reality there are implicit conversion under the wraps. This commit makes them explicit, for clarity.
2022-06-22Streamline RoomPowerLevelsEvent backoffice codeAlexey Rusakov
Also: leave a link at the place in the spec with power level defaults to make it clear they are not invented out of thin air.
2022-06-22Address a few more Sonar warningsAlexey Rusakov
2022-06-22Clean up RequestData from Sonar warningsAlexey Rusakov
Also: make ImplPtr more flexible.
2022-06-22Use fixed width types for enumsAlexey Rusakov
2022-06-22More .clang-tidy tweaksAlexey Rusakov
2022-06-21Fix a few clang-tidy/GCC warningsAlexey Rusakov