Fixes a set of bugs introduced by 00b77144c1,
where we replaced explicit `RoomVersionId` matches with `version < V11`
comparisons. The `Ord` impl on `RoomVersionId` does not work like that,
and is in fact a lexicographic string comparison[1]. The most visible
effect of these bugs is that incoming redaction events would sometimes
be ignored.
Instead of reverting to the explicit matches, which were quite verbose,
I implemented a `RoomVersion` struct that has flags for each property
that we care about. This is similar to the approach used by ruma[2] and
synapse[3].
[1]: 7cfa3be0c6/crates/ruma-common/src/identifiers/room_version_id.rs (L136)
[2]: 7cfa3be0c6/crates/ruma-state-res/src/room_version.rs
[3]: c856ae4724/synapse/api/room_versions.py
This method did _a lot_ of things at the same time. In order to use
`KeyValueDatabase` for the migrate-db command, we need to be able to
open a db without attempting to apply all the migrations and without
spawning a bunch of unrelated background tasks.
The state after this refactor is still not great, but it's enough to do
a migration tool.
Errors will show up in the logs in this case with detailed information
about what broke.
In the future we should add some kind of database integrity check
functionality and also functionality to repair/delete broken data, but
for now this at least makes it work 99.99% of the time.
File data is inserted into the database before being created on disk,
which means that it's possible for data to exist in the database that
doesn't exist on disk. In this case, the media deletion functions should
simply ignore this error.
It's possible for a server to have multiple associated public keys. This can happen when a Matrix server is set up on a particular domain, its key is lost, and the server continues running on the domain. Now there will be two keys associated to the domain. The old logic wouldn't fetch the new key if we already had the old key cached. The new logic will fetch any keys we don't have that we need, rather than just fetching one key per server.
Previous behavior was causing us to error out of the entire
state_cache::update_membership function when it saw an invalid m.direct,
making it impossible for affected users to join upgraded rooms. This bug
is especially bad if an affected user attempts to upgrade a room,
because we will fail to create their join event in the new room, leaving
both rooms permanently bricked.
The new behavior should never prevent users from joining a room based on
the contents of their account data, and should migrate the `m.direct`
event in a reasonable way even if it is partially corrupted by the
element bug.
This also fixes a bug where the previous implementation will
unintentionally remove any keys that aren't part of the expected
m.direct schema. I don't know of any cases where this came up in
practice.
Fixes: #46
The implementation inside each function is unchanged from the original.
I intend to clean up and fix bugs in later commits, so the diff will be
more clear.