diff --git a/.github/workflows/bindings_ci.yml b/.github/workflows/bindings_ci.yml index f8ccf951d..7c338b10c 100644 --- a/.github/workflows/bindings_ci.yml +++ b/.github/workflows/bindings_ci.yml @@ -162,7 +162,7 @@ jobs: with: command: install # keep in sync with uniffi dependency in Cargo.toml's - args: uniffi_bindgen --git https://github.com/mozilla/uniffi-rs --rev 6d6724a26b119032588c5b3d59ac4d09f902e778 + args: uniffi_bindgen --git https://github.com/mozilla/uniffi-rs --rev 091c3561656e72e1a4160412c83b36d98e556d06 - name: Generate .xcframework working-directory: bindings/apple diff --git a/Cargo.lock b/Cargo.lock index 67c4c76d3..775eb23bf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -57,9 +57,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "0.7.18" +version = "0.7.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e" dependencies = [ "memchr", ] @@ -75,9 +75,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.61" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "508b352bb5c066aac251f6daf6b36eccd03e8a88e8081cd44959ea277a3af9a8" +checksum = "b9a8f622bcf6ff3df478e9deba3e03e4e04b300f8e6a139e192c05fa3490afc7" [[package]] name = "anymap2" @@ -278,7 +278,7 @@ dependencies = [ "cc", "cfg-if", "libc", - "miniz_oxide 0.5.3", + "miniz_oxide 0.5.4", "object", "rustc-demangle", ] @@ -291,9 +291,9 @@ checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" [[package]] name = "base64ct" -version = "1.5.1" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bdca834647821e0b13d9539a8634eb62d3501b6b6c2cec1722786ee6671b851" +checksum = "ea2b2456fd614d856680dcd9fcc660a51a820fa09daef2e49772b56a193c8474" [[package]] name = "benchmarks" @@ -365,9 +365,9 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" +checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" dependencies = [ "generic-array", ] @@ -401,15 +401,15 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.10.0" +version = "3.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3" +checksum = "c1ad822118d20d2c234f427000d5acc36eabe1e29a348c89b63dd60b13f28e5d" [[package]] name = "bytemuck" -version = "1.11.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5377c8865e74a160d21f29c2d40669f53286db6eab59b88540cbb12ffc8b835" +checksum = "2f5715e491b5a1598fc2bef5a606847b5dc1d48ea625bd3c02c00de8285591da" [[package]] name = "byteorder" @@ -431,9 +431,9 @@ checksum = "c1db59621ec70f09c5e9b597b220c7a2b43611f4710dc03ceb8748637775692c" [[package]] name = "camino" -version = "1.0.9" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "869119e97797867fd90f5e22af7d0bd274bd4635ebb9eb68c04f3f513ae6c412" +checksum = "88ad0e1e3e88dd237a156ab9f571021b8a158caa0ae44b1968a241efb5144c1e" dependencies = [ "serde", ] @@ -697,9 +697,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.2" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" +checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" dependencies = [ "libc", ] @@ -898,13 +898,14 @@ dependencies = [ [[package]] name = "dashmap" -version = "5.3.4" +version = "5.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3495912c9c1ccf2e18976439f4443f3fee0fd61f424ff99fde6a66b15ecb448f" +checksum = "907076dfda823b0b36d2a1bb5f90c96660a5bbcd7729e10727f07858f22c4edc" dependencies = [ "cfg-if", "hashbrown 0.12.3", "lock_api", + "once_cell", "parking_lot_core 0.9.3", ] @@ -946,15 +947,6 @@ dependencies = [ "byteorder", ] -[[package]] -name = "deflate" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c86f7e25f518f4b81808a2cf1c50996a61f5c2eb394b2393bd87f2a4780a432f" -dependencies = [ - "adler32", -] - [[package]] name = "der" version = "0.5.1" @@ -1010,7 +1002,7 @@ version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" dependencies = [ - "block-buffer 0.10.2", + "block-buffer 0.10.3", "crypto-common", "subtle", ] @@ -1100,9 +1092,9 @@ dependencies = [ [[package]] name = "either" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f107b87b6afc2a64fd13cac55fe06d6c8859f12d4b14cbcdd2c67d0976781be" +checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" [[package]] name = "encoding_rs" @@ -1119,26 +1111,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "enum_variant_macros" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c8ebc2ec69ce7b33aaac0d8f341a4a02a63aa3d5f0e5fe616b2d910e892fa5f" -dependencies = [ - "enum_variant_macros_macros", -] - -[[package]] -name = "enum_variant_macros_macros" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64422f7dc8e3cb58ce5bc5410b0cc55e22afee6a714f4906a43d4a5f9a79045e" -dependencies = [ - "proc-macro2 1.0.43", - "quote 1.0.21", - "syn 1.0.99", -] - [[package]] name = "env_logger" version = "0.9.0" @@ -1384,7 +1356,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6" dependencies = [ "crc32fast", - "miniz_oxide 0.5.3", + "miniz_oxide 0.5.4", ] [[package]] @@ -1410,19 +1382,18 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "form_urlencoded" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" +checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" dependencies = [ - "matches", "percent-encoding", ] [[package]] name = "fs-err" -version = "2.7.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bd79fa345a495d3ae89fb7165fec01c0e72f41821d642dda363a1e97975652e" +checksum = "64db3e262960f0662f43a6366788d5f10f7f244b8f7d7d987f560baf5ded5c50" [[package]] name = "fs2" @@ -1442,9 +1413,9 @@ checksum = "2022715d62ab30faffd124d40b76f4134a550a87792276512b18d63272333394" [[package]] name = "futures" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" +checksum = "7f21eda599937fba36daeb58a22e8f5cee2d14c4a17b5b7739c7c8e5e3b8230c" dependencies = [ "futures-channel", "futures-core", @@ -1457,9 +1428,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" +checksum = "30bdd20c28fadd505d0fd6712cdfcb0d4b5648baf45faef7f852afb2399bb050" dependencies = [ "futures-core", "futures-sink", @@ -1467,15 +1438,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" +checksum = "4e5aa3de05362c3fb88de6531e6296e85cde7739cccad4b9dfeeb7f6ebce56bf" [[package]] name = "futures-executor" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" +checksum = "9ff63c23854bee61b6e9cd331d523909f238fc7636290b96826e9cfa5faa00ab" dependencies = [ "futures-core", "futures-task", @@ -1484,9 +1455,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" +checksum = "bbf4d2a7a308fd4578637c0b17c7e1c7ba127b8f6ba00b29f717e9655d85eb68" [[package]] name = "futures-lite" @@ -1505,9 +1476,9 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" +checksum = "42cd15d1c7456c04dbdf7e88bcd69760d74f3a798d6444e16974b505b0e62f17" dependencies = [ "proc-macro2 1.0.43", "quote 1.0.21", @@ -1529,15 +1500,15 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" +checksum = "21b20ba5a92e727ba30e72834706623d94ac93a725410b6a6b6fbc1b07f7ba56" [[package]] name = "futures-task" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" +checksum = "a6508c467c73851293f390476d4491cf4d227dbabcd4170f3bb6044959b294f1" [[package]] name = "futures-timer" @@ -1547,9 +1518,9 @@ checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" [[package]] name = "futures-util" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" +checksum = "44fb6cb1be61cc1d2e43b262516aafcf63b241cffdb1d3fa115f91d9c7b09c90" dependencies = [ "futures-channel", "futures-core", @@ -1660,9 +1631,9 @@ checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" [[package]] name = "goblin" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91766b1121940d622933a13e20665857648681816089c9bc2075c4b75a6e4f6b" +checksum = "a7666983ed0dd8d21a6f6576ee00053ca0926fb281a5522577a4dbd0f1b54143" dependencies = [ "log", "plain", @@ -1671,9 +1642,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37a82c6d637fc9515a4694bbf1cb2457b79d81ce52b3108bdeea58b07dd34a57" +checksum = "5ca32592cf21ac7ccab1825cd87f6c9b3d9022c44d086172ed0966bec8af30be" dependencies = [ "bytes", "fnv", @@ -1684,7 +1655,7 @@ dependencies = [ "indexmap", "slab", "tokio", - "tokio-util 0.7.3", + "tokio-util 0.7.4", "tracing", ] @@ -1714,9 +1685,9 @@ dependencies = [ [[package]] name = "headers" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cff78e5788be1e0ab65b04d306b2ed5092c815ec97ec70f4ebd5aee158aa55d" +checksum = "f3e372db8e5c0d213e0cd0b9be18be2aca3d44cf2fe30a9d46a65581cd454584" dependencies = [ "base64", "bitflags", @@ -1725,7 +1696,7 @@ dependencies = [ "http", "httpdate", "mime", - "sha-1", + "sha1", ] [[package]] @@ -1815,9 +1786,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.7.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "496ce29bb5a52785b44e0f7ca2847ae0bb839c9bd28f69acac9b99d461c0c04c" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" [[package]] name = "httpdate" @@ -1889,11 +1860,10 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "0.2.3" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" dependencies = [ - "matches", "unicode-bidi", "unicode-normalization", ] @@ -1930,7 +1900,7 @@ dependencies = [ "jpeg-decoder 0.2.6", "num-rational 0.4.1", "num-traits", - "png 0.17.5", + "png 0.17.6", "scoped_threadpool", "tiff 0.7.3", ] @@ -2019,9 +1989,9 @@ dependencies = [ [[package]] name = "io-lifetimes" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24c3f4eff5495aee4c0399d7b6a0dc2b6e81be84242ffbfcf253ebacccc1d0cb" +checksum = "1ea37f355c05dde75b84bba2d767906ad522e97cd9e2eef2be7a4ab7fb442c06" [[package]] name = "ipnet" @@ -2103,9 +2073,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.129" +version = "0.2.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64de3cc433455c14174d42e554d4027ee631c4d046d43e3ecc6efc4636cdc7a7" +checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5" [[package]] name = "libloading" @@ -2125,9 +2095,9 @@ checksum = "d4d2456c373231a208ad294c33dc5bff30051eafd954cd4caae83a712b12854d" [[package]] name = "lock_api" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" +checksum = "9f80bf5aacaf25cbfc8210d1cfb718f2bf3b11c4c54e5afe36c236853a8ec390" dependencies = [ "autocfg", "scopeguard", @@ -2192,6 +2162,7 @@ dependencies = [ "async-trait", "backoff", "bytes", + "ctor", "dashmap", "dirs", "event-listener", @@ -2330,7 +2301,7 @@ dependencies = [ "ruma", "serde", "serde_json", - "sha2 0.10.2", + "sha2 0.10.5", "thiserror", "tokio", "tracing", @@ -2355,7 +2326,7 @@ dependencies = [ "ruma", "serde", "serde_json", - "sha2 0.10.2", + "sha2 0.10.5", "tempfile", "thiserror", "tokio", @@ -2464,10 +2435,12 @@ version = "0.1.0" dependencies = [ "anyhow", "assign", + "ctor", "matrix-sdk", "once_cell", "tempfile", "tokio", + "tracing-subscriber", ] [[package]] @@ -2526,7 +2499,7 @@ dependencies = [ "rand 0.8.5", "serde", "serde_json", - "sha2 0.10.2", + "sha2 0.10.5", "thiserror", "zeroize", ] @@ -2562,9 +2535,9 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "memmap2" -version = "0.5.5" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a79b39c93a7a5a27eeaf9a23b5ff43f1b9e0ad6b1cdd441140ae53c35613fc7" +checksum = "95af15f345b17af2efc8ead6080fb8bc376f8cec1b35277b935637595fe77498" dependencies = [ "libc", ] @@ -2621,9 +2594,9 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc" +checksum = "96590ba8f175222643a85693f33d26e9c8a015f599c216509b1a6894af675d34" dependencies = [ "adler", ] @@ -2860,9 +2833,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.13.0" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1" +checksum = "2f7254b99e31cad77da24b08ebf628882739a608578bb1bcdfc1f9c21260d7c0" [[package]] name = "oorandom" @@ -2923,9 +2896,9 @@ dependencies = [ [[package]] name = "os_str_bytes" -version = "6.2.0" +version = "6.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "648001efe5d5c0102d8cea768e348da85d90af8ba91f0bea908f157951493cd4" +checksum = "9ff7415e9ae3fff1225851df9e0d9e4e5479f947619774677a63572e55e80eff" [[package]] name = "parking" @@ -2994,9 +2967,9 @@ dependencies = [ [[package]] name = "paste" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9423e2b32f7a043629287a536f21951e8c6a82482d0acb1eeebfc90bc2225b22" +checksum = "b1de2e551fb905ac83f73f7aedf2f0cb4a0da7e35efa24a202a936269f1f18e1" [[package]] name = "pbkdf2" @@ -3007,29 +2980,29 @@ dependencies = [ "digest 0.10.3", "hmac", "password-hash", - "sha2 0.10.2", + "sha2 0.10.5", ] [[package]] name = "percent-encoding" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" +checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" [[package]] name = "pin-project" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78203e83c48cffbe01e4a2d35d566ca4de445d79a85372fc64e378bfc812a260" +checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "710faf75e1b33345361201d36d04e98ac1ed8909151a017ed384700836104c74" +checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" dependencies = [ "proc-macro2 1.0.43", "quote 1.0.21", @@ -3072,9 +3045,9 @@ checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" [[package]] name = "plotters" -version = "0.3.2" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9428003b84df1496fb9d6eeee9c5f8145cb41ca375eb0dad204328888832811f" +checksum = "2538b639e642295546c50fcd545198c9d64ee2a38620a628724a3b266d5fbf97" dependencies = [ "num-traits", "plotters-backend", @@ -3091,9 +3064,9 @@ checksum = "193228616381fecdc1224c62e96946dfbc73ff4384fba576e052ff8c1bea8142" [[package]] name = "plotters-svg" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0918736323d1baff32ee0eade54984f6f201ad7e97d5cfb5d6ab4a358529615" +checksum = "f9a81d2759aae1dae668f783c308bc5c8ebd191ff4184aaa1b37f65a6ae5a56f" dependencies = [ "plotters-backend", ] @@ -3106,20 +3079,20 @@ checksum = "3c3287920cb847dee3de33d301c463fba14dda99db24214ddf93f83d3021f4c6" dependencies = [ "bitflags", "crc32fast", - "deflate 0.8.6", + "deflate", "miniz_oxide 0.3.7", ] [[package]] name = "png" -version = "0.17.5" +version = "0.17.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc38c0ad57efb786dd57b9864e5b18bae478c00c824dc55a38bbc9da95dde3ba" +checksum = "8f0e7f4c94ec26ff209cee506314212639d6c91b80afb82984819fafce9df01c" dependencies = [ "bitflags", "crc32fast", - "deflate 1.0.0", - "miniz_oxide 0.5.3", + "flate2", + "miniz_oxide 0.5.4", ] [[package]] @@ -3135,9 +3108,9 @@ dependencies = [ [[package]] name = "pprof" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bba88ee898c63351101af3e60c66c5398c517681ce533eef8caff10ecf11ec1" +checksum = "d6472bfed9475542ac46c518734a8d06d71b0f6cb2c17f904aa301711a57786f" dependencies = [ "backtrace", "cfg-if", @@ -3674,9 +3647,9 @@ checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" [[package]] name = "rustix" -version = "0.35.7" +version = "0.35.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d51cc38aa10f6bbb377ed28197aa052aa4e2b762c22be9d3153d01822587e787" +checksum = "72c825b8aa8010eb9ee99b75f05e10180b9278d161583034d7574c9d617aeada" dependencies = [ "bitflags", "errno", @@ -3825,9 +3798,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.6.1" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dc14f172faf8a0194a3aded622712b0de276821addc574fa54fc0a1167e10dc" +checksum = "2bc1bb97804af6631813c55739f771071e0f2ed33ee20b68c86ec505d906356c" dependencies = [ "bitflags", "core-foundation", @@ -3857,9 +3830,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.143" +version = "1.0.144" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53e8e5d5b70924f74ff5c6d64d9a5acd91422117c60f48c4e07855238a254553" +checksum = "0f747710de3dcd43b88c9168773254e809d8ddbdf9653b84e2554ab219f17860" dependencies = [ "serde_derive", ] @@ -3885,9 +3858,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.143" +version = "1.0.144" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3d8e8de557aee63c26b85b947f5e59b690d0454c753f3adeb5cd7835ab88391" +checksum = "94ed3a816fb1d101812f83e789f888322c34e291f894f19590dc310963e87a00" dependencies = [ "proc-macro2 1.0.43", "quote 1.0.21", @@ -3896,9 +3869,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.83" +version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38dd04e3c8279e75b31ef29dbdceebfe5ad89f4d0937213c53f7d49d01b3d5a7" +checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44" dependencies = [ "itoa 1.0.3", "ryu", @@ -3930,9 +3903,9 @@ dependencies = [ [[package]] name = "serde_yaml" -version = "0.9.4" +version = "0.9.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79b7c9017c64a49806c6e8df8ef99b92446d09c92457f85f91835b01a8064ae0" +checksum = "89f31df3f50926cdf2855da5fd8812295c34752cb20438dae42a67f79e021ac3" dependencies = [ "indexmap", "itoa 1.0.3", @@ -3942,10 +3915,10 @@ dependencies = [ ] [[package]] -name = "sha-1" -version = "0.10.0" +name = "sha1" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "028f48d513f9678cda28f6e4064755b3fbb2af6acd672f2c209b62323f7aea0f" +checksum = "006769ba83e921b3085caa8334186b00cf92b4cb1a6cf4632fbccc8eff5c7549" dependencies = [ "cfg-if", "cpufeatures", @@ -3967,9 +3940,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.2" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55deaec60f81eefe3cce0dc50bda92d6d8e88f2a27df7c5033b42afeb1ed2676" +checksum = "cf9db03534dff993187064c4e0c05a5708d2a9728ace9a8959b77bedf415dac5" dependencies = [ "cfg-if", "cpufeatures", @@ -3987,9 +3960,9 @@ dependencies = [ [[package]] name = "signature" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f054c6c1a6e95179d6f23ed974060dcefb2d9388bb7256900badad682c499de4" +checksum = "f0ea32af43239f0d353a7dd75a22d94c329c8cdaafdcb4c1c1335aa10c298a4a" [[package]] name = "slab" @@ -4041,9 +4014,9 @@ checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1" [[package]] name = "socket2" -version = "0.4.4" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" +checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" dependencies = [ "libc", "winapi", @@ -4218,18 +4191,18 @@ checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" [[package]] name = "thiserror" -version = "1.0.32" +version = "1.0.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5f6586b7f764adc0231f4c79be7b920e766bb2f3e51b3661cdb263828f19994" +checksum = "8c1b05ca9d106ba7d2e31a9dab4a64e7be2cce415321966ea3132c49a656e252" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.32" +version = "1.0.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12bafc5b54507e0149cdf1b145a5d80ab80a90bcd9275df43d4fff68460f6c21" +checksum = "e8f2591983642de85c921015f3f070c665a197ed69e417af436115e3a1407487" dependencies = [ "proc-macro2 1.0.43", "quote 1.0.21", @@ -4269,9 +4242,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db76ff9fa4b1458b3c7f077f3ff9887394058460d21e634355b273aaf11eea45" +checksum = "3c3f9a28b618c3a6b9251b6908e9c99e04b9e5c02e6581ccbb67d59c34ef7f9b" dependencies = [ "itoa 1.0.3", "libc", @@ -4305,9 +4278,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.20.1" +version = "1.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a8325f63a7d4774dd041e363b2409ed1c5cbbd0f867795e661df066b2b0a581" +checksum = "89797afd69d206ccd11fb0ea560a44bbb87731d020670e79416d442919257d42" dependencies = [ "autocfg", "bytes", @@ -4393,9 +4366,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc463cd8deddc3770d20f9852143d50bf6094e640b485cb2e189a2099085ff45" +checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740" dependencies = [ "bytes", "futures-core", @@ -4552,8 +4525,8 @@ checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04" [[package]] name = "uniffi" -version = "0.19.3" -source = "git+https://github.com/mozilla/uniffi-rs?rev=6d6724a26b119032588c5b3d59ac4d09f902e778#6d6724a26b119032588c5b3d59ac4d09f902e778" +version = "0.19.6" +source = "git+https://github.com/mozilla/uniffi-rs?rev=091c3561656e72e1a4160412c83b36d98e556d06#091c3561656e72e1a4160412c83b36d98e556d06" dependencies = [ "anyhow", "bytes", @@ -4568,14 +4541,13 @@ dependencies = [ [[package]] name = "uniffi_bindgen" -version = "0.19.3" -source = "git+https://github.com/mozilla/uniffi-rs?rev=6d6724a26b119032588c5b3d59ac4d09f902e778#6d6724a26b119032588c5b3d59ac4d09f902e778" +version = "0.19.6" +source = "git+https://github.com/mozilla/uniffi-rs?rev=091c3561656e72e1a4160412c83b36d98e556d06#091c3561656e72e1a4160412c83b36d98e556d06" dependencies = [ "anyhow", "askama", "bincode", "camino", - "cargo_metadata", "clap 3.2.20", "fs-err", "goblin", @@ -4591,8 +4563,8 @@ dependencies = [ [[package]] name = "uniffi_build" -version = "0.19.3" -source = "git+https://github.com/mozilla/uniffi-rs?rev=6d6724a26b119032588c5b3d59ac4d09f902e778#6d6724a26b119032588c5b3d59ac4d09f902e778" +version = "0.19.6" +source = "git+https://github.com/mozilla/uniffi-rs?rev=091c3561656e72e1a4160412c83b36d98e556d06#091c3561656e72e1a4160412c83b36d98e556d06" dependencies = [ "anyhow", "camino", @@ -4601,20 +4573,17 @@ dependencies = [ [[package]] name = "uniffi_macros" -version = "0.19.3" -source = "git+https://github.com/mozilla/uniffi-rs?rev=6d6724a26b119032588c5b3d59ac4d09f902e778#6d6724a26b119032588c5b3d59ac4d09f902e778" +version = "0.19.6" +source = "git+https://github.com/mozilla/uniffi-rs?rev=091c3561656e72e1a4160412c83b36d98e556d06#091c3561656e72e1a4160412c83b36d98e556d06" dependencies = [ "bincode", "camino", - "extension-trait", "fs-err", - "glob", "once_cell", "proc-macro2 1.0.43", "quote 1.0.21", "serde", "syn 1.0.99", - "tempfile", "toml", "uniffi_build", "uniffi_meta", @@ -4622,11 +4591,9 @@ dependencies = [ [[package]] name = "uniffi_meta" -version = "0.19.3" -source = "git+https://github.com/mozilla/uniffi-rs?rev=6d6724a26b119032588c5b3d59ac4d09f902e778#6d6724a26b119032588c5b3d59ac4d09f902e778" +version = "0.19.6" +source = "git+https://github.com/mozilla/uniffi-rs?rev=091c3561656e72e1a4160412c83b36d98e556d06#091c3561656e72e1a4160412c83b36d98e556d06" dependencies = [ - "bincode", - "enum_variant_macros", "serde", ] @@ -4654,13 +4621,12 @@ checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" [[package]] name = "url" -version = "2.2.2" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" +checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" dependencies = [ "form_urlencoded", "idna", - "matches", "percent-encoding", "serde", ] @@ -4724,7 +4690,7 @@ dependencies = [ "rand 0.7.3", "serde", "serde_json", - "sha2 0.10.2", + "sha2 0.10.5", "subtle", "thiserror", "x25519-dalek", @@ -4950,7 +4916,7 @@ dependencies = [ [[package]] name = "weedle2" version = "4.0.0" -source = "git+https://github.com/mozilla/uniffi-rs?rev=6d6724a26b119032588c5b3d59ac4d09f902e778#6d6724a26b119032588c5b3d59ac4d09f902e778" +source = "git+https://github.com/mozilla/uniffi-rs?rev=091c3561656e72e1a4160412c83b36d98e556d06#091c3561656e72e1a4160412c83b36d98e556d06" dependencies = [ "nom", ] diff --git a/bindings/apple/build_xcframework.sh b/bindings/apple/build_xcframework.sh index adcc58d5d..222d0e48d 100755 --- a/bindings/apple/build_xcframework.sh +++ b/bindings/apple/build_xcframework.sh @@ -52,7 +52,7 @@ lipo -create \ # Architecture for the .a file argument doesn't matter, since the API is the same on all uniffi-bindgen generate \ --language swift \ - --cdylib "${TARGET_DIR}/x86_64-apple-darwin/${REL_TYPE_DIR}/libmatrix_sdk_ffi.a" \ + --lib-file "${TARGET_DIR}/x86_64-apple-darwin/${REL_TYPE_DIR}/libmatrix_sdk_ffi.a" \ --out-dir ${GENERATED_DIR} \ "${SRC_ROOT}/bindings/matrix-sdk-ffi/src/api.udl" diff --git a/bindings/apple/debug_build_xcframework.sh b/bindings/apple/debug_build_xcframework.sh index 5af747bc4..920a2d474 100755 --- a/bindings/apple/debug_build_xcframework.sh +++ b/bindings/apple/debug_build_xcframework.sh @@ -49,7 +49,7 @@ lipo -create \ # Generate uniffi files uniffi-bindgen generate \ --language swift \ - --cdylib "${TARGET_DIR}/$TARGET/${REL_TYPE_DIR}/libmatrix_sdk_ffi.a" \ + --lib-file "${TARGET_DIR}/$TARGET/${REL_TYPE_DIR}/libmatrix_sdk_ffi.a" \ --out-dir ${GENERATED_DIR} \ "${SRC_ROOT}/bindings/matrix-sdk-ffi/src/api.udl" diff --git a/bindings/matrix-sdk-crypto-ffi/Cargo.toml b/bindings/matrix-sdk-crypto-ffi/Cargo.toml index b828d7429..8e9643afb 100644 --- a/bindings/matrix-sdk-crypto-ffi/Cargo.toml +++ b/bindings/matrix-sdk-crypto-ffi/Cargo.toml @@ -28,7 +28,7 @@ thiserror = "1.0.30" tracing = "0.1.34" tracing-subscriber = { version = "0.3.11", features = ["env-filter"] } # keep in sync with uniffi dependency in matrix-sdk-ffi, and uniffi_bindgen in ffi CI job -uniffi = { git = "https://github.com/mozilla/uniffi-rs", rev = "6d6724a26b119032588c5b3d59ac4d09f902e778" } +uniffi = { git = "https://github.com/mozilla/uniffi-rs", rev = "091c3561656e72e1a4160412c83b36d98e556d06" } zeroize = { version = "1.3.0", features = ["zeroize_derive"] } [dependencies.js_int] @@ -60,7 +60,7 @@ git = "https://github.com/matrix-org/vodozemac/" rev = "ad1f098aff2a0b69aa5822c4e0679089a9fa4a86" [build-dependencies] -uniffi_build = { git = "https://github.com/mozilla/uniffi-rs", rev = "6d6724a26b119032588c5b3d59ac4d09f902e778", features = ["builtin-bindgen"] } +uniffi_build = { git = "https://github.com/mozilla/uniffi-rs", rev = "091c3561656e72e1a4160412c83b36d98e556d06", features = ["builtin-bindgen"] } [dev-dependencies] tempfile = "3.3.0" diff --git a/bindings/matrix-sdk-crypto-nodejs/src/machine.rs b/bindings/matrix-sdk-crypto-nodejs/src/machine.rs index 3347ac184..fd3149d6d 100644 --- a/bindings/matrix-sdk-crypto-nodejs/src/machine.rs +++ b/bindings/matrix-sdk-crypto-nodejs/src/machine.rs @@ -135,8 +135,7 @@ impl OlmMachine { /// /// # Arguments /// - /// * `to_device_events`, thhe to-device events of the current sync - /// response. + /// * `to_device_events`, the to-device events of the current sync response. /// * `changed_devices`, the list of devices that changed in this sync /// response. /// * `one_time_keys_count`, the current one-time keys counts that the sync diff --git a/bindings/matrix-sdk-ffi/Cargo.toml b/bindings/matrix-sdk-ffi/Cargo.toml index 7a2b9c064..9ca8576fd 100644 --- a/bindings/matrix-sdk-ffi/Cargo.toml +++ b/bindings/matrix-sdk-ffi/Cargo.toml @@ -14,7 +14,7 @@ crate-type = ["staticlib"] [build-dependencies] -uniffi_build = { git = "https://github.com/mozilla/uniffi-rs", rev = "6d6724a26b119032588c5b3d59ac4d09f902e778", features = ["builtin-bindgen"] } +uniffi_build = { git = "https://github.com/mozilla/uniffi-rs", rev = "091c3561656e72e1a4160412c83b36d98e556d06", features = ["builtin-bindgen"] } [dependencies] anyhow = "1.0.51" @@ -32,5 +32,5 @@ tokio-stream = "0.1.8" tracing = "0.1.32" tracing-subscriber = { version = "0.3", features = ["env-filter"] } # keep in sync with uniffi dependency in matrix-sdk-crypto-ffi, and uniffi_bindgen in ffi CI job -uniffi = { git = "https://github.com/mozilla/uniffi-rs", rev = "6d6724a26b119032588c5b3d59ac4d09f902e778" } -uniffi_macros = { git = "https://github.com/mozilla/uniffi-rs", rev = "6d6724a26b119032588c5b3d59ac4d09f902e778" } +uniffi = { git = "https://github.com/mozilla/uniffi-rs", rev = "091c3561656e72e1a4160412c83b36d98e556d06" } +uniffi_macros = { git = "https://github.com/mozilla/uniffi-rs", rev = "091c3561656e72e1a4160412c83b36d98e556d06" } diff --git a/bindings/matrix-sdk-ffi/src/api.udl b/bindings/matrix-sdk-ffi/src/api.udl index d10066166..eca28e102 100644 --- a/bindings/matrix-sdk-ffi/src/api.udl +++ b/bindings/matrix-sdk-ffi/src/api.udl @@ -1,7 +1,4 @@ -namespace matrix_sdk_ffi { - MediaSource media_source_from_url(string url); - MessageEventContent message_event_content_from_markdown(string md); -}; +namespace matrix_sdk_ffi {}; [Error] interface ClientError { @@ -39,21 +36,11 @@ interface Client { [Throws=ClientError] void restore_login(string restore_token); - string homeserver(); - void start_sync(u16? timeline_limit); [Throws=ClientError] string restore_token(); - boolean is_guest(); - - boolean has_first_synced(); - - boolean is_syncing(); - - boolean is_soft_logout(); - [Throws=ClientError] string user_id(); @@ -72,8 +59,6 @@ interface Client { [Throws=ClientError] void set_account_data(string event_type, string content); - sequence rooms(); - [Throws=ClientError] sequence get_media_content(MediaSource source); diff --git a/bindings/matrix-sdk-ffi/src/client.rs b/bindings/matrix-sdk-ffi/src/client.rs index 20d7d633d..614c6b371 100644 --- a/bindings/matrix-sdk-ffi/src/client.rs +++ b/bindings/matrix-sdk-ffi/src/client.rs @@ -92,11 +92,6 @@ impl Client { *self.delegate.write().unwrap() = delegate; } - /// The homeserver this client is configured to use. - pub fn homeserver(&self) -> String { - RUNTIME.block_on(async move { self.async_homeserver().await }) - } - pub async fn async_homeserver(&self) -> String { self.client.homeserver().await.to_string() } @@ -200,27 +195,6 @@ impl Client { }); } - /// Indication whether we've received a first sync response since - /// establishing the client (in memory) - pub fn has_first_synced(&self) -> bool { - self.state.read().unwrap().has_first_synced - } - - /// Indication whether we are currently syncing - pub fn is_syncing(&self) -> bool { - self.state.read().unwrap().has_first_synced - } - - /// Flag indicating whether the session is in soft logout mode - pub fn is_soft_logout(&self) -> bool { - self.state.read().unwrap().is_soft_logout - } - - /// Is this a guest account? - pub fn is_guest(&self) -> bool { - self.state.read().unwrap().is_guest - } - pub fn restore_token(&self) -> anyhow::Result { RUNTIME.block_on(async move { let session = self.client.session().expect("Missing session"); @@ -234,10 +208,6 @@ impl Client { }) } - pub fn rooms(&self) -> Vec> { - self.client.rooms().into_iter().map(|room| Arc::new(Room::new(room))).collect() - } - pub fn user_id(&self) -> anyhow::Result { let user_id = self.client.user_id().expect("No User ID found"); Ok(user_id.to_string()) @@ -333,6 +303,39 @@ impl Client { } } +#[uniffi::export] +impl Client { + /// The homeserver this client is configured to use. + pub fn homeserver(&self) -> String { + RUNTIME.block_on(async move { self.async_homeserver().await }) + } + + /// Indication whether we've received a first sync response since + /// establishing the client (in memory) + pub fn has_first_synced(&self) -> bool { + self.state.read().unwrap().has_first_synced + } + + /// Indication whether we are currently syncing + pub fn is_syncing(&self) -> bool { + self.state.read().unwrap().has_first_synced + } + + /// Is this a guest account? + pub fn is_guest(&self) -> bool { + self.state.read().unwrap().is_guest + } + + /// Flag indicating whether the session is in soft logout mode + pub fn is_soft_logout(&self) -> bool { + self.state.read().unwrap().is_soft_logout + } + + pub fn rooms(&self) -> Vec> { + self.client.rooms().into_iter().map(|room| Arc::new(Room::new(room))).collect() + } +} + #[uniffi::export] fn gen_transaction_id() -> String { TransactionId::new().to_string() diff --git a/bindings/matrix-sdk-ffi/src/lib.rs b/bindings/matrix-sdk-ffi/src/lib.rs index c5b04d9a2..214c6a5a8 100644 --- a/bindings/matrix-sdk-ffi/src/lib.rs +++ b/bindings/matrix-sdk-ffi/src/lib.rs @@ -66,3 +66,9 @@ fn setup_tracing(configuration: String) { .with(fmt::layer().with_ansi(false)) .init(); } + +mod uniffi_types { + pub use matrix_sdk::ruma::events::room::{ + message::RoomMessageEventContent as MessageEventContent, MediaSource, + }; +} diff --git a/bindings/matrix-sdk-ffi/src/messages.rs b/bindings/matrix-sdk-ffi/src/messages.rs index 216c801ee..587433742 100644 --- a/bindings/matrix-sdk-ffi/src/messages.rs +++ b/bindings/matrix-sdk-ffi/src/messages.rs @@ -235,10 +235,12 @@ pub fn sync_event_to_message(sync_event: SyncTimelineEvent) -> Option Arc { Arc::new(MediaSource::Plain(url.into())) } +#[uniffi::export] pub fn message_event_content_from_markdown(md: String) -> Arc { Arc::new(MessageEventContent::text_markdown(md)) } diff --git a/crates/matrix-sdk-base/Cargo.toml b/crates/matrix-sdk-base/Cargo.toml index 0b9a96afc..b3f5b16fe 100644 --- a/crates/matrix-sdk-base/Cargo.toml +++ b/crates/matrix-sdk-base/Cargo.toml @@ -56,6 +56,8 @@ http = "0.2.6" assign = "1.1.1" env_logger = "0.9.0" matrix-sdk-test = { version = "0.5.0", path = "../../testing/matrix-sdk-test" } + +[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] tokio = { version = "1.17.0", default-features = false, features = ["rt-multi-thread", "macros"] } [target.'cfg(target_arch = "wasm32")'.dev-dependencies] diff --git a/crates/matrix-sdk-base/src/client.rs b/crates/matrix-sdk-base/src/client.rs index a1afc8156..b035a832a 100644 --- a/crates/matrix-sdk-base/src/client.rs +++ b/crates/matrix-sdk-base/src/client.rs @@ -239,7 +239,7 @@ impl BaseClient { } #[cfg(feature = "e2e-encryption")] - async fn handle_unenecrypted_verification_event( + async fn handle_unencrypted_verification_event( &self, event: &AnySyncMessageLikeEvent, room_id: &RoomId, @@ -353,12 +353,12 @@ impl BaseClient { ruma::events::room::message::MessageType::VerificationRequest( _, ) => { - self.handle_unenecrypted_verification_event(e, room_id).await?; + self.handle_unencrypted_verification_event(e, room_id).await?; } _ => (), }, _ if e.event_type().to_string().starts_with("m.key.verification") => { - self.handle_unenecrypted_verification_event(e, room_id).await?; + self.handle_unencrypted_verification_event(e, room_id).await?; } _ => (), }, diff --git a/crates/matrix-sdk-base/src/rooms/members.rs b/crates/matrix-sdk-base/src/rooms/members.rs index 2308f3a30..e1179997a 100644 --- a/crates/matrix-sdk-base/src/rooms/members.rs +++ b/crates/matrix-sdk-base/src/rooms/members.rs @@ -111,10 +111,6 @@ impl RoomMember { /// Get the membership state of this member. pub fn membership(&self) -> &MembershipState { - if let Some(p) = self.profile.as_ref() { - p.membership() - } else { - self.event.membership() - } + self.event.membership() } } diff --git a/crates/matrix-sdk-base/src/rooms/normal.rs b/crates/matrix-sdk-base/src/rooms/normal.rs index 6b511254f..d2e9a70f9 100644 --- a/crates/matrix-sdk-base/src/rooms/normal.rs +++ b/crates/matrix-sdk-base/src/rooms/normal.rs @@ -840,6 +840,7 @@ mod test { use std::sync::Arc; use assign::assign; + use matrix_sdk_test::async_test; use ruma::{ event_id, events::{ @@ -893,7 +894,7 @@ mod test { }) } - #[tokio::test] + #[async_test] async fn test_display_name_default() { let _ = env_logger::try_init(); let (_, room) = make_room(RoomType::Joined); @@ -931,7 +932,7 @@ mod test { assert_eq!(room.display_name().await.unwrap(), DisplayName::Named("Test Room".to_owned())); } - #[tokio::test] + #[async_test] async fn test_display_name_dm_invited() { let _ = env_logger::try_init(); let (store, room) = make_room(RoomType::Invited); @@ -954,7 +955,7 @@ mod test { ); } - #[tokio::test] + #[async_test] async fn test_display_name_dm_invited_no_heroes() { let _ = env_logger::try_init(); let (store, room) = make_room(RoomType::Invited); @@ -973,7 +974,7 @@ mod test { ); } - #[tokio::test] + #[async_test] async fn test_display_name_dm_joined() { let _ = env_logger::try_init(); let (store, room) = make_room(RoomType::Joined); @@ -1005,7 +1006,7 @@ mod test { ); } - #[tokio::test] + #[async_test] async fn test_display_name_dm_joined_no_heroes() { let _ = env_logger::try_init(); let (store, room) = make_room(RoomType::Joined); @@ -1031,7 +1032,8 @@ mod test { DisplayName::Calculated("Matthew".to_owned()) ); } - #[tokio::test] + + #[async_test] async fn test_display_name_dm_alone() { let _ = env_logger::try_init(); let (store, room) = make_room(RoomType::Joined); diff --git a/crates/matrix-sdk-base/src/store/integration_tests.rs b/crates/matrix-sdk-base/src/store/integration_tests.rs index ce911a381..24edc61b4 100644 --- a/crates/matrix-sdk-base/src/store/integration_tests.rs +++ b/crates/matrix-sdk-base/src/store/integration_tests.rs @@ -647,6 +647,53 @@ macro_rules! statestore_integration_tests { Ok(()) } + #[async_test] + async fn test_stripped_non_stripped() -> StoreResult<()> { + let store = get_store().await.unwrap(); + let room_id = room_id!("!test_stripped_non_stripped:localhost"); + let user_id = user_id(); + + assert!(store.get_member_event(room_id, user_id).await.unwrap().is_none()); + assert_eq!(store.get_room_infos().await.unwrap().len(), 0); + assert_eq!(store.get_stripped_room_infos().await.unwrap().len(), 0); + + let mut changes = StateChanges::default(); + changes + .members + .entry(room_id.to_owned()) + .or_default() + .insert(user_id.to_owned(), membership_event()); + changes.add_room(RoomInfo::new(room_id, RoomType::Left)); + store.save_changes(&changes).await.unwrap(); + + assert!(matches!( + store.get_member_event(room_id, user_id).await.unwrap(), + Some(matrix_sdk_common::deserialized_responses::MemberEvent::Sync(_)) + )); + assert_eq!(store.get_room_infos().await.unwrap().len(), 1); + assert_eq!(store.get_stripped_room_infos().await.unwrap().len(), 0); + + let members = store.get_user_ids(room_id).await.unwrap(); + assert_eq!(members, vec![user_id.to_owned()]); + + let mut changes = StateChanges::default(); + changes.add_stripped_member(room_id, custom_stripped_membership_event(user_id)); + changes.add_stripped_room(RoomInfo::new(room_id, RoomType::Invited)); + store.save_changes(&changes).await.unwrap(); + + assert!(matches!( + store.get_member_event(room_id, user_id).await.unwrap(), + Some(matrix_sdk_common::deserialized_responses::MemberEvent::Stripped(_)) + )); + assert_eq!(store.get_room_infos().await.unwrap().len(), 0); + assert_eq!(store.get_stripped_room_infos().await.unwrap().len(), 1); + + let members = store.get_user_ids(room_id).await.unwrap(); + assert_eq!(members, vec![user_id.to_owned()]); + + Ok(()) + } + #[async_test] async fn test_room_removal() -> StoreResult<()> { let room_id = room_id(); diff --git a/crates/matrix-sdk-base/src/store/memory_store.rs b/crates/matrix-sdk-base/src/store/memory_store.rs index fad2aed61..e58fe082c 100644 --- a/crates/matrix-sdk-base/src/store/memory_store.rs +++ b/crates/matrix-sdk-base/src/store/memory_store.rs @@ -156,6 +156,9 @@ impl MemoryStore { for (room, events) in &changes.members { for event in events.values() { + self.stripped_joined_user_ids.remove(room); + self.stripped_invited_user_ids.remove(room); + match event.membership() { MembershipState::Join => { self.joined_user_ids @@ -193,6 +196,7 @@ impl MemoryStore { .entry(room.clone()) .or_default() .insert(event.state_key().to_owned(), event.clone()); + self.stripped_members.remove(room); } } @@ -236,12 +240,14 @@ impl MemoryStore { .entry(event_type.clone()) .or_default() .insert(state_key.to_owned(), event.clone()); + self.stripped_room_state.remove(room); } } } for (room_id, room_info) in &changes.room_infos { self.room_info.insert(room_id.clone(), room_info.clone()); + self.stripped_room_infos.remove(room_id); } for (sender, event) in &changes.presence { @@ -250,6 +256,7 @@ impl MemoryStore { for (room_id, info) in &changes.stripped_room_infos { self.stripped_room_infos.insert(room_id.clone(), info.clone()); + self.room_info.remove(room_id); } for (room, events) in &changes.stripped_members { @@ -258,31 +265,31 @@ impl MemoryStore { MembershipState::Join => { self.stripped_joined_user_ids .entry(room.clone()) - .or_insert_with(DashSet::new) + .or_default() .insert(event.state_key.clone()); self.stripped_invited_user_ids .entry(room.clone()) - .or_insert_with(DashSet::new) + .or_default() .remove(&event.state_key); } MembershipState::Invite => { self.stripped_invited_user_ids .entry(room.clone()) - .or_insert_with(DashSet::new) + .or_default() .insert(event.state_key.clone()); self.stripped_joined_user_ids .entry(room.clone()) - .or_insert_with(DashSet::new) + .or_default() .remove(&event.state_key); } _ => { self.stripped_joined_user_ids .entry(room.clone()) - .or_insert_with(DashSet::new) + .or_default() .remove(&event.state_key); self.stripped_invited_user_ids .entry(room.clone()) - .or_insert_with(DashSet::new) + .or_default() .remove(&event.state_key); } } @@ -502,23 +509,24 @@ impl MemoryStore { room_id: &RoomId, state_key: &UserId, ) -> Result> { - if let Some(e) = self.members.get(room_id).and_then(|m| m.get(state_key).map(|m| m.clone())) - { - Ok(Some(MemberEvent::Sync(e))) - } else if let Some(e) = + if let Some(e) = self.stripped_members.get(room_id).and_then(|m| m.get(state_key).map(|m| m.clone())) { Ok(Some(MemberEvent::Stripped(e))) + } else if let Some(e) = + self.members.get(room_id).and_then(|m| m.get(state_key).map(|m| m.clone())) + { + Ok(Some(MemberEvent::Sync(e))) } else { Ok(None) } } fn get_user_ids(&self, room_id: &RoomId) -> Vec { - if let Some(u) = self.members.get(room_id) { + if let Some(u) = self.stripped_members.get(room_id) { u.iter().map(|u| u.key().clone()).collect() } else { - self.stripped_members + self.members .get(room_id) .map(|u| u.iter().map(|u| u.key().clone()).collect()) .unwrap_or_default() @@ -752,19 +760,19 @@ impl StateStore for MemoryStore { } async fn get_invited_user_ids(&self, room_id: &RoomId) -> Result> { - let v = self.get_invited_user_ids(room_id); + let v = self.get_stripped_invited_user_ids(room_id); if !v.is_empty() { return Ok(v); } - Ok(self.get_stripped_invited_user_ids(room_id)) + Ok(self.get_invited_user_ids(room_id)) } async fn get_joined_user_ids(&self, room_id: &RoomId) -> Result> { - let v = self.get_joined_user_ids(room_id); + let v = self.get_stripped_joined_user_ids(room_id); if !v.is_empty() { return Ok(v); } - Ok(self.get_stripped_joined_user_ids(room_id)) + Ok(self.get_joined_user_ids(room_id)) } async fn get_room_infos(&self) -> Result> { diff --git a/crates/matrix-sdk-base/src/store/mod.rs b/crates/matrix-sdk-base/src/store/mod.rs index 49b85c93d..63fca7cc1 100644 --- a/crates/matrix-sdk-base/src/store/mod.rs +++ b/crates/matrix-sdk-base/src/store/mod.rs @@ -617,6 +617,9 @@ impl Store { let user_id = &self.session_meta.get().expect("Creating room while not being logged in").user_id; + // Remove the respective room from non-stripped rooms. + self.rooms.remove(room_id); + self.stripped_rooms .entry(room_id.to_owned()) .or_insert_with(|| Room::new(user_id, self.inner.clone(), room_id, RoomType::Invited)) @@ -633,6 +636,9 @@ impl Store { let user_id = &self.session_meta.get().expect("Creating room while not being logged in").user_id; + // Remove the respective room from stripped rooms. + self.stripped_rooms.remove(room_id); + self.rooms .entry(room_id.to_owned()) .or_insert_with(|| Room::new(user_id, self.inner.clone(), room_id, room_type)) diff --git a/crates/matrix-sdk-indexeddb/src/state_store.rs b/crates/matrix-sdk-indexeddb/src/state_store.rs index f5b18e341..33d68ca5f 100644 --- a/crates/matrix-sdk-indexeddb/src/state_store.rs +++ b/crates/matrix-sdk-indexeddb/src/state_store.rs @@ -13,7 +13,7 @@ // limitations under the License. use std::{ - collections::BTreeSet, + collections::{BTreeSet, HashSet}, sync::{ atomic::{AtomicBool, Ordering}, Arc, @@ -563,33 +563,38 @@ impl IndexeddbStateStore { } pub async fn save_changes(&self, changes: &StateChanges) -> Result<()> { - let mut stores: Vec<&'static str> = [ + let mut stores: HashSet<&'static str> = [ (changes.sync_token.is_some(), KEYS::SYNC_TOKEN), (changes.session.is_some(), KEYS::SESSION), (!changes.ambiguity_maps.is_empty(), KEYS::DISPLAY_NAMES), (!changes.account_data.is_empty(), KEYS::ACCOUNT_DATA), (!changes.presence.is_empty(), KEYS::PRESENCE), (!changes.profiles.is_empty(), KEYS::PROFILES), - (!changes.state.is_empty(), KEYS::ROOM_STATE), (!changes.room_account_data.is_empty(), KEYS::ROOM_ACCOUNT_DATA), - #[cfg(feature = "experimental-timeline")] - (!changes.room_infos.is_empty() || !changes.timeline.is_empty(), KEYS::ROOM_INFOS), - #[cfg(not(feature = "experimental-timeline"))] - (!changes.room_infos.is_empty(), KEYS::ROOM_INFOS), (!changes.receipts.is_empty(), KEYS::ROOM_EVENT_RECEIPTS), (!changes.stripped_state.is_empty(), KEYS::STRIPPED_ROOM_STATE), - (!changes.stripped_room_infos.is_empty(), KEYS::STRIPPED_ROOM_INFOS), ] .iter() .filter_map(|(id, key)| if *id { Some(*key) } else { None }) .collect(); + if !changes.state.is_empty() { + stores.extend([KEYS::ROOM_STATE, KEYS::STRIPPED_ROOM_STATE]); + } + + if !changes.room_infos.is_empty() || !changes.stripped_room_infos.is_empty() { + stores.extend([KEYS::ROOM_INFOS, KEYS::STRIPPED_ROOM_INFOS]); + } + if !changes.members.is_empty() { stores.extend([ KEYS::PROFILES, KEYS::MEMBERS, KEYS::INVITED_USER_IDS, KEYS::JOINED_USER_IDS, + KEYS::STRIPPED_MEMBERS, + KEYS::STRIPPED_INVITED_USER_IDS, + KEYS::STRIPPED_JOINED_USER_IDS, ]) } @@ -608,6 +613,7 @@ impl IndexeddbStateStore { #[cfg(feature = "experimental-timeline")] if !changes.timeline.is_empty() { stores.extend([ + KEYS::ROOM_INFOS, KEYS::ROOM_TIMELINE, KEYS::ROOM_TIMELINE_METADATA, KEYS::ROOM_EVENT_ID_TO_POSITION, @@ -619,6 +625,7 @@ impl IndexeddbStateStore { return Ok(()); } + let stores: Vec<&'static str> = stores.into_iter().collect(); let tx = self.inner.transaction_on_multi_with_mode(&stores, IdbTransactionMode::Readwrite)?; @@ -659,24 +666,28 @@ impl IndexeddbStateStore { } if !changes.state.is_empty() { - let store = tx.object_store(KEYS::ROOM_STATE)?; + let state = tx.object_store(KEYS::ROOM_STATE)?; + let stripped_state = tx.object_store(KEYS::STRIPPED_ROOM_STATE)?; for (room, event_types) in &changes.state { for (event_type, events) in event_types { for (state_key, event) in events { let key = self.encode_key(KEYS::ROOM_STATE, (room, event_type, state_key)); - store.put_key_val(&key, &self.serialize_event(&event)?)?; + state.put_key_val(&key, &self.serialize_event(&event)?)?; + stripped_state.delete(&key)?; } } } } if !changes.room_infos.is_empty() { - let store = tx.object_store(KEYS::ROOM_INFOS)?; + let room_infos = tx.object_store(KEYS::ROOM_INFOS)?; + let stripped_room_infos = tx.object_store(KEYS::STRIPPED_ROOM_INFOS)?; for (room_id, room_info) in &changes.room_infos { - store.put_key_val( + room_infos.put_key_val( &self.encode_key(KEYS::ROOM_INFOS, room_id), &self.serialize_event(&room_info)?, )?; + stripped_room_infos.delete(&self.encode_key(KEYS::STRIPPED_ROOM_INFOS, room_id))?; } } @@ -691,12 +702,14 @@ impl IndexeddbStateStore { } if !changes.stripped_room_infos.is_empty() { - let store = tx.object_store(KEYS::STRIPPED_ROOM_INFOS)?; + let stripped_room_infos = tx.object_store(KEYS::STRIPPED_ROOM_INFOS)?; + let room_infos = tx.object_store(KEYS::ROOM_INFOS)?; for (room_id, info) in &changes.stripped_room_infos { - store.put_key_val( + stripped_room_infos.put_key_val( &self.encode_key(KEYS::STRIPPED_ROOM_INFOS, room_id), &self.serialize_event(&info)?, )?; + room_infos.delete(&self.encode_key(KEYS::ROOM_INFOS, room_id))?; } } @@ -752,10 +765,13 @@ impl IndexeddbStateStore { } if !changes.members.is_empty() { - let profiles_store = tx.object_store(KEYS::PROFILES)?; + let profiles = tx.object_store(KEYS::PROFILES)?; let joined = tx.object_store(KEYS::JOINED_USER_IDS)?; let invited = tx.object_store(KEYS::INVITED_USER_IDS)?; let members = tx.object_store(KEYS::MEMBERS)?; + let stripped_members = tx.object_store(KEYS::STRIPPED_MEMBERS)?; + let stripped_joined = tx.object_store(KEYS::STRIPPED_JOINED_USER_IDS)?; + let stripped_invited = tx.object_store(KEYS::STRIPPED_INVITED_USER_IDS)?; for (room, events) in &changes.members { let profile_changes = changes.profiles.get(room); @@ -763,6 +779,11 @@ impl IndexeddbStateStore { for event in events.values() { let key = (room, event.state_key()); + stripped_joined + .delete(&self.encode_key(KEYS::STRIPPED_JOINED_USER_IDS, key))?; + stripped_invited + .delete(&self.encode_key(KEYS::STRIPPED_INVITED_USER_IDS, key))?; + match event.membership() { MembershipState::Join => { joined.put_key_val_owned( @@ -788,9 +809,10 @@ impl IndexeddbStateStore { &self.encode_key(KEYS::MEMBERS, key), &self.serialize_event(&event)?, )?; + stripped_members.delete(&self.encode_key(KEYS::STRIPPED_MEMBERS, key))?; if let Some(profile) = profile_changes.and_then(|p| p.get(event.state_key())) { - profiles_store.put_key_val_owned( + profiles.put_key_val_owned( &self.encode_key(KEYS::PROFILES, key), &self.serialize_event(&profile)?, )?; @@ -1104,16 +1126,6 @@ impl IndexeddbStateStore { state_key: &UserId, ) -> Result> { if let Some(e) = self - .inner - .transaction_on_one_with_mode(KEYS::MEMBERS, IdbTransactionMode::Readonly)? - .object_store(KEYS::MEMBERS)? - .get(&self.encode_key(KEYS::MEMBERS, (room_id, state_key)))? - .await? - .map(|f| self.deserialize_event(f)) - .transpose()? - { - Ok(Some(MemberEvent::Sync(e))) - } else if let Some(e) = self .inner .transaction_on_one_with_mode(KEYS::STRIPPED_MEMBERS, IdbTransactionMode::Readonly)? .object_store(KEYS::STRIPPED_MEMBERS)? @@ -1123,6 +1135,16 @@ impl IndexeddbStateStore { .transpose()? { Ok(Some(MemberEvent::Stripped(e))) + } else if let Some(e) = self + .inner + .transaction_on_one_with_mode(KEYS::MEMBERS, IdbTransactionMode::Readonly)? + .object_store(KEYS::MEMBERS)? + .get(&self.encode_key(KEYS::MEMBERS, (room_id, state_key)))? + .await? + .map(|f| self.deserialize_event(f)) + .transpose()? + { + Ok(Some(MemberEvent::Sync(e))) } else { Ok(None) } @@ -1542,27 +1564,27 @@ impl StateStore for IndexeddbStateStore { } async fn get_user_ids(&self, room_id: &RoomId) -> StoreResult> { - let ids: Vec = self.get_user_ids_stream(room_id).await?; + let ids: Vec = self.get_stripped_user_ids_stream(room_id).await?; if !ids.is_empty() { return Ok(ids); } - self.get_stripped_user_ids_stream(room_id).await.map_err(|e| e.into()) + self.get_user_ids_stream(room_id).await.map_err(|e| e.into()) } async fn get_invited_user_ids(&self, room_id: &RoomId) -> StoreResult> { - let ids: Vec = self.get_invited_user_ids(room_id).await?; + let ids: Vec = self.get_stripped_invited_user_ids(room_id).await?; if !ids.is_empty() { return Ok(ids); } - self.get_stripped_invited_user_ids(room_id).await.map_err(|e| e.into()) + self.get_invited_user_ids(room_id).await.map_err(|e| e.into()) } async fn get_joined_user_ids(&self, room_id: &RoomId) -> StoreResult> { - let ids: Vec = self.get_joined_user_ids(room_id).await?; + let ids: Vec = self.get_stripped_joined_user_ids(room_id).await?; if !ids.is_empty() { return Ok(ids); } - self.get_stripped_joined_user_ids(room_id).await.map_err(|e| e.into()) + self.get_joined_user_ids(room_id).await.map_err(|e| e.into()) } async fn get_room_infos(&self) -> StoreResult> { diff --git a/crates/matrix-sdk-sled/src/state_store.rs b/crates/matrix-sdk-sled/src/state_store.rs index 9739db4f0..cb542e9eb 100644 --- a/crates/matrix-sdk-sled/src/state_store.rs +++ b/crates/matrix-sdk-sled/src/state_store.rs @@ -603,7 +603,7 @@ impl SledStateStore { room_account_data, stripped_joined, stripped_invited, - striped_rooms, + stripped_rooms, stripped_members, stripped_state, )| { @@ -613,6 +613,11 @@ impl SledStateStore { for event in events.values() { let key = (room, event.state_key()); + stripped_joined + .remove(self.encode_key(STRIPPED_JOINED_USER_ID, key))?; + stripped_invited + .remove(self.encode_key(STRIPPED_INVITED_USER_ID, key))?; + match event.membership() { MembershipState::Join => { joined.insert( @@ -641,6 +646,7 @@ impl SledStateStore { self.serialize_value(&event) .map_err(ConflictableTransactionError::Abort)?, )?; + stripped_members.remove(self.encode_key(STRIPPED_ROOM_MEMBER, key))?; if let Some(profile) = profile_changes.and_then(|p| p.get(event.state_key())) @@ -682,6 +688,10 @@ impl SledStateStore { self.serialize_value(&event) .map_err(ConflictableTransactionError::Abort)?, )?; + stripped_state.remove(self.encode_key( + STRIPPED_ROOM_STATE, + (room, event_type, state_key), + ))?; } } } @@ -692,14 +702,16 @@ impl SledStateStore { self.serialize_value(room_info) .map_err(ConflictableTransactionError::Abort)?, )?; + stripped_rooms.remove(self.encode_key(STRIPPED_ROOM_INFO, room_id))?; } for (room_id, info) in &changes.stripped_room_infos { - striped_rooms.insert( + stripped_rooms.insert( self.encode_key(STRIPPED_ROOM_INFO, room_id), self.serialize_value(&info) .map_err(ConflictableTransactionError::Abort)?, )?; + rooms.remove(self.encode_key(ROOM, room_id))?; } for (room, events) in &changes.stripped_members { @@ -905,15 +917,17 @@ impl SledStateStore { let key = self.encode_key(MEMBER, (room_id, state_key)); let stripped_key = self.encode_key(STRIPPED_ROOM_MEMBER, (room_id, state_key)); spawn_blocking(move || { - if let Some(e) = db.members.get(key)?.map(|v| db.deserialize_value(&v)).transpose()? { - Ok(Some(MemberEvent::Sync(e))) - } else if let Some(e) = db + if let Some(e) = db .stripped_members .get(stripped_key)? .map(|v| db.deserialize_value(&v)) .transpose()? { Ok(Some(MemberEvent::Stripped(e))) + } else if let Some(e) = + db.members.get(key)?.map(|v| db.deserialize_value(&v)).transpose()? + { + Ok(Some(MemberEvent::Sync(e))) } else { Ok(None) } @@ -1169,6 +1183,13 @@ impl SledStateStore { members_batch.remove(key?); } + let mut stripped_members_batch = sled::Batch::default(); + for key in + self.stripped_members.scan_prefix(self.encode_key(STRIPPED_ROOM_MEMBER, room_id)).keys() + { + stripped_members_batch.remove(key?); + } + let mut profiles_batch = sled::Batch::default(); for key in self.profiles.scan_prefix(self.encode_key(PROFILE, room_id)).keys() { profiles_batch.remove(key?); @@ -1185,6 +1206,15 @@ impl SledStateStore { joined_user_ids_batch.remove(key?); } + let mut stripped_joined_user_ids_batch = sled::Batch::default(); + for key in self + .stripped_joined_user_ids + .scan_prefix(self.encode_key(STRIPPED_JOINED_USER_ID, room_id)) + .keys() + { + stripped_joined_user_ids_batch.remove(key?); + } + let mut invited_user_ids_batch = sled::Batch::default(); for key in self.invited_user_ids.scan_prefix(self.encode_key(INVITED_USER_ID, room_id)).keys() @@ -1192,25 +1222,20 @@ impl SledStateStore { invited_user_ids_batch.remove(key?); } + let mut stripped_invited_user_ids_batch = sled::Batch::default(); + for key in self + .stripped_invited_user_ids + .scan_prefix(self.encode_key(STRIPPED_INVITED_USER_ID, room_id)) + .keys() + { + stripped_invited_user_ids_batch.remove(key?); + } + let mut room_state_batch = sled::Batch::default(); for key in self.room_state.scan_prefix(self.encode_key(ROOM_STATE, room_id)).keys() { room_state_batch.remove(key?); } - let mut room_account_data_batch = sled::Batch::default(); - for key in - self.room_account_data.scan_prefix(self.encode_key(ROOM_ACCOUNT_DATA, room_id)).keys() - { - room_account_data_batch.remove(key?); - } - - let mut stripped_members_batch = sled::Batch::default(); - for key in - self.stripped_members.scan_prefix(self.encode_key(STRIPPED_ROOM_MEMBER, room_id)).keys() - { - stripped_members_batch.remove(key?); - } - let mut stripped_room_state_batch = sled::Batch::default(); for key in self .stripped_room_state @@ -1220,6 +1245,64 @@ impl SledStateStore { stripped_room_state_batch.remove(key?); } + let mut room_account_data_batch = sled::Batch::default(); + for key in + self.room_account_data.scan_prefix(self.encode_key(ROOM_ACCOUNT_DATA, room_id)).keys() + { + room_account_data_batch.remove(key?); + } + + let ret: Result<(), TransactionError> = ( + &self.members, + &self.stripped_members, + &self.profiles, + &self.display_names, + &self.joined_user_ids, + &self.stripped_joined_user_ids, + &self.invited_user_ids, + &self.stripped_invited_user_ids, + &self.room_info, + &self.stripped_room_infos, + &self.room_state, + &self.stripped_room_state, + &self.room_account_data, + ) + .transaction( + |( + members, + stripped_members, + profiles, + display_names, + joined, + stripped_joined, + invited, + stripped_invited, + rooms, + stripped_rooms, + state, + stripped_state, + room_account_data, + )| { + rooms.remove(self.encode_key(ROOM, room_id))?; + stripped_rooms.remove(self.encode_key(STRIPPED_ROOM_INFO, room_id))?; + + members.apply_batch(&members_batch)?; + stripped_members.apply_batch(&stripped_members_batch)?; + profiles.apply_batch(&profiles_batch)?; + display_names.apply_batch(&display_names_batch)?; + joined.apply_batch(&joined_user_ids_batch)?; + stripped_joined.apply_batch(&stripped_joined_user_ids_batch)?; + invited.apply_batch(&invited_user_ids_batch)?; + stripped_invited.apply_batch(&stripped_invited_user_ids_batch)?; + state.apply_batch(&room_state_batch)?; + stripped_state.apply_batch(&stripped_room_state_batch)?; + room_account_data.apply_batch(&room_account_data_batch)?; + + Ok(()) + }, + ); + ret?; + let mut room_user_receipts_batch = sled::Batch::default(); for key in self.room_user_receipts.scan_prefix(self.encode_key(ROOM_USER_RECEIPT, room_id)).keys() @@ -1236,56 +1319,14 @@ impl SledStateStore { room_event_receipts_batch.remove(key?); } - let ret: Result<(), TransactionError> = ( - &self.members, - &self.profiles, - &self.display_names, - &self.joined_user_ids, - &self.invited_user_ids, - &self.room_info, - &self.room_state, - &self.room_account_data, - &self.stripped_room_infos, - &self.stripped_members, - &self.stripped_room_state, - &self.room_user_receipts, - &self.room_event_receipts, - ) - .transaction( - |( - members, - profiles, - display_names, - joined, - invited, - rooms, - state, - room_account_data, - stripped_rooms, - stripped_members, - stripped_state, - room_user_receipts, - room_event_receipts, - )| { - rooms.remove(self.encode_key(ROOM, room_id))?; - stripped_rooms.remove(self.encode_key(STRIPPED_ROOM_INFO, room_id))?; - - members.apply_batch(&members_batch)?; - profiles.apply_batch(&profiles_batch)?; - display_names.apply_batch(&display_names_batch)?; - joined.apply_batch(&joined_user_ids_batch)?; - invited.apply_batch(&invited_user_ids_batch)?; - state.apply_batch(&room_state_batch)?; - room_account_data.apply_batch(&room_account_data_batch)?; - stripped_members.apply_batch(&stripped_members_batch)?; - stripped_state.apply_batch(&stripped_room_state_batch)?; + let ret: Result<(), TransactionError> = + (&self.room_user_receipts, &self.room_event_receipts).transaction( + |(room_user_receipts, room_event_receipts)| { room_user_receipts.apply_batch(&room_user_receipts_batch)?; room_event_receipts.apply_batch(&room_event_receipts_batch)?; - Ok(()) }, ); - ret?; #[cfg(feature = "experimental-timeline")] @@ -1599,27 +1640,30 @@ impl StateStore for SledStateStore { } async fn get_user_ids(&self, room_id: &RoomId) -> StoreResult> { - let v: Vec = self.get_user_ids_stream(room_id).await?.try_collect().await?; + let v: Vec = + self.get_stripped_user_ids_stream(room_id).await?.try_collect().await?; if !v.is_empty() { return Ok(v); } - self.get_stripped_user_ids_stream(room_id).await?.try_collect().await + self.get_user_ids_stream(room_id).await?.try_collect().await } async fn get_invited_user_ids(&self, room_id: &RoomId) -> StoreResult> { - let v: Vec = self.get_invited_user_ids(room_id).await?.try_collect().await?; + let v: Vec = + self.get_stripped_invited_user_ids(room_id).await?.try_collect().await?; if !v.is_empty() { return Ok(v); } - self.get_stripped_invited_user_ids(room_id).await?.try_collect().await + self.get_invited_user_ids(room_id).await?.try_collect().await } async fn get_joined_user_ids(&self, room_id: &RoomId) -> StoreResult> { - let v: Vec = self.get_joined_user_ids(room_id).await?.try_collect().await?; + let v: Vec = + self.get_stripped_joined_user_ids(room_id).await?.try_collect().await?; if !v.is_empty() { return Ok(v); } - self.get_stripped_joined_user_ids(room_id).await?.try_collect().await + self.get_joined_user_ids(room_id).await?.try_collect().await } async fn get_room_infos(&self) -> StoreResult> { diff --git a/crates/matrix-sdk/Cargo.toml b/crates/matrix-sdk/Cargo.toml index 77ac91646..995884d57 100644 --- a/crates/matrix-sdk/Cargo.toml +++ b/crates/matrix-sdk/Cargo.toml @@ -150,5 +150,6 @@ getrandom = { version = "0.2.6", default-features = false, features = ["js"] } wasm-bindgen-test = "0.3.30" [target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] +ctor = "0.1.23" tokio = { version = "1.17.0", default-features = false, features = ["rt-multi-thread", "macros"] } wiremock = "0.5.13" diff --git a/crates/matrix-sdk/src/client/mod.rs b/crates/matrix-sdk/src/client/mod.rs index d704ef086..0d3d26c85 100644 --- a/crates/matrix-sdk/src/client/mod.rs +++ b/crates/matrix-sdk/src/client/mod.rs @@ -70,8 +70,8 @@ use ruma::{ SyncStateEvent, }, presence::PresenceState, - DeviceId, OwnedDeviceId, OwnedRoomId, OwnedServerName, RoomAliasId, RoomId, RoomOrAliasId, - ServerName, UInt, UserId, + DeviceId, MilliSecondsSinceUnixEpoch, OwnedDeviceId, OwnedRoomId, OwnedServerName, RoomAliasId, + RoomId, RoomOrAliasId, ServerName, UInt, UserId, }; use serde::de::DeserializeOwned; #[cfg(not(target_arch = "wasm32"))] @@ -152,8 +152,8 @@ pub(crate) struct ClientInner { /// flight per room. #[cfg(feature = "e2e-encryption")] pub(crate) group_session_locks: DashMap>>, - #[cfg(feature = "e2e-encryption")] /// Lock making sure we're only doing one key claim request at a time. + #[cfg(feature = "e2e-encryption")] pub(crate) key_claim_lock: Mutex<()>, pub(crate) members_request_locks: DashMap>>, pub(crate) typing_notice_times: DashMap, @@ -256,8 +256,8 @@ impl Client { /// * `transaction_id` - The id of the transaction, used to guard against /// the same transaction being sent twice. This guarding currently isn't /// implemented. - /// * `incoming_transaction` - The sync response converted from a - /// transaction received from the homeserver. + /// * `sync_response` - The sync response converted from a transaction + /// received from the homeserver. /// /// [transaction]: https://matrix.org/docs/spec/application_service/r0.1.2#put-matrix-app-v1-transactions-txnid #[cfg(feature = "appservice")] @@ -590,6 +590,12 @@ impl Client { /// // You can omit any or all arguments after the first. /// }); /// + /// // Registering a temporary event handler: + /// let handle = client.add_event_handler(|ev: SyncRoomMessageEvent| async move { + /// /* Event handler */ + /// }); + /// client.remove_event_handler(handle); + /// /// // Custom events work exactly the same way, you just need to declare /// // the content struct and use the EventContent derive macro on it. /// #[derive(Clone, Debug, Deserialize, Serialize, EventContent)] @@ -1586,13 +1592,16 @@ impl Client { let user_id = self.user_id().ok_or(Error::AuthenticationRequired)?.to_owned(); + let now = MilliSecondsSinceUnixEpoch::now(); let handle = self.add_room_event_handler(room_id, { move |event: SyncStateEvent, room: room::Room| { let mut tx = tx.clone(); let user_id = user_id.clone(); async move { - if *event.membership() == MembershipState::Join && *event.state_key() == user_id + if *event.membership() == MembershipState::Join + && *event.state_key() == user_id + && event.origin_server_ts() > now { debug!("received RoomMemberEvent corresponding to requested join"); @@ -1646,13 +1655,16 @@ impl Client { let user_id = self.user_id().ok_or(Error::AuthenticationRequired)?.to_owned(); + let now = MilliSecondsSinceUnixEpoch::now(); let handle = self.add_event_handler({ move |event: SyncStateEvent, room: room::Room| { let mut tx = tx.clone(); let user_id = user_id.clone(); async move { - if *event.membership() == MembershipState::Join && *event.state_key() == user_id + if *event.membership() == MembershipState::Join + && *event.state_key() == user_id + && event.origin_server_ts() > now { if let Err(e) = tx.send(room).await { debug!( @@ -1775,12 +1787,17 @@ impl Client { let user_id = self.user_id().ok_or(Error::AuthenticationRequired)?.to_owned(); + let now = MilliSecondsSinceUnixEpoch::now(); let handle = self.add_event_handler({ move |event: SyncStateEvent, room: room::Room| { let mut tx = tx.clone(); let user_id = user_id.clone(); async move { + if event.origin_server_ts() <= now { + return; + } + let event_content = if let Some(original_event) = event.as_original() { &original_event.content } else { @@ -1831,6 +1848,45 @@ impl Client { } } + /// Create a direct message room with the specified user. + pub async fn create_dm_room(&self, user_id: &UserId) -> Result { + use ruma::{ + api::client::room::create_room::v3::RoomPreset, events::direct::DirectEventContent, + }; + + // First we create the DM room, where we invite the user and tell the + // invitee that the room should be a DM. + let invite = &[user_id.to_owned()]; + + let request = assign!(ruma::api::client::room::create_room::v3::Request::new(), { + invite, + is_direct: true, + preset: Some(RoomPreset::TrustedPrivateChat), + }); + + let room = self.create_room(request).await?; + + // Now we need to mark the room as a DM for ourselves, we fetch the + // existing `m.direct` event and append the room to the list of DMs we + // have with this user. + let mut content = self + .account() + .account_data::() + .await? + .map(|c| c.deserialize()) + .transpose()? + .unwrap_or_default(); + + content.entry(user_id.to_owned()).or_default().push(room.room_id().to_owned()); + + // TODO We should probably save the fact that we need to send this out + // because otherwise we might end up in a state where we have a DM that + // isn't marked as one. + self.account().set_account_data(content).await?; + + Ok(room) + } + /// Search the homeserver's directory for public rooms with a filter. /// /// # Arguments diff --git a/crates/matrix-sdk/src/config/sync.rs b/crates/matrix-sdk/src/config/sync.rs index d2a761e16..e6536171a 100644 --- a/crates/matrix-sdk/src/config/sync.rs +++ b/crates/matrix-sdk/src/config/sync.rs @@ -12,14 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::time::Duration; +use std::{fmt, time::Duration}; use ruma::api::client::sync::sync_events; const DEFAULT_SYNC_TIMEOUT: Duration = Duration::from_secs(30); -#[derive(Debug, Clone)] /// Settings for a sync call. +#[derive(Clone)] pub struct SyncSettings<'a> { pub(crate) filter: Option>, pub(crate) timeout: Option, @@ -33,6 +33,26 @@ impl<'a> Default for SyncSettings<'a> { } } +impl<'a> fmt::Debug for SyncSettings<'a> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut s = f.debug_struct("SyncSettings"); + + macro_rules! opt_field { + ($field:ident) => { + if let Some(value) = &self.$field { + s.field(stringify!($field), value); + } + }; + } + + opt_field!(filter); + opt_field!(timeout); + opt_field!(token); + + s.field("full_state", &self.full_state).finish() + } +} + impl<'a> SyncSettings<'a> { /// Create new default sync settings. #[must_use] diff --git a/crates/matrix-sdk/src/encryption/identities/users.rs b/crates/matrix-sdk/src/encryption/identities/users.rs index 9e8d27248..7f790aae3 100644 --- a/crates/matrix-sdk/src/encryption/identities/users.rs +++ b/crates/matrix-sdk/src/encryption/identities/users.rs @@ -475,12 +475,8 @@ impl OtherUserIdentity { room.invite_user_by_id(self.inner.user_id()).await?; } room.clone() - } else if let Some(room) = - self.client.create_dm_room(self.inner.user_id().to_owned()).await? - { - room } else { - return Err(RequestVerificationError::RoomCreation(self.inner.user_id().to_owned())); + self.client.create_dm_room(self.inner.user_id()).await? }; let response = room diff --git a/crates/matrix-sdk/src/encryption/mod.rs b/crates/matrix-sdk/src/encryption/mod.rs index 5e07e798f..db437e12e 100644 --- a/crates/matrix-sdk/src/encryption/mod.rs +++ b/crates/matrix-sdk/src/encryption/mod.rs @@ -38,7 +38,6 @@ pub use matrix_sdk_base::crypto::{ use matrix_sdk_base::crypto::{ CrossSigningStatus, OutgoingRequest, RoomMessageRequest, ToDeviceRequest, }; -use matrix_sdk_common::instant::Duration; #[cfg(feature = "e2e-encryption")] use ruma::OwnedDeviceId; use ruma::{ @@ -57,14 +56,13 @@ use ruma::{ }; use tracing::{debug, instrument, trace, warn}; -pub use crate::error::RoomKeyImportError; use crate::{ attachment::{AttachmentInfo, Thumbnail}, encryption::{ identities::{Device, UserDevices}, verification::{SasVerification, Verification, VerificationRequest}, }, - error::HttpResult, + error::{HttpResult, RoomKeyImportError}, room, Client, Error, Result, }; @@ -226,57 +224,6 @@ impl Client { }) } - #[cfg(feature = "e2e-encryption")] - pub(crate) async fn create_dm_room( - &self, - user_id: OwnedUserId, - ) -> Result> { - use ruma::{ - api::client::room::create_room::v3::RoomPreset, events::direct::DirectEventContent, - }; - - const SYNC_WAIT_TIME: Duration = Duration::from_secs(3); - - // First we create the DM room, where we invite the user and tell the - // invitee that the room should be a DM. - let invite = &[user_id.clone()]; - - let request = assign!(ruma::api::client::room::create_room::v3::Request::new(), { - invite, - is_direct: true, - preset: Some(RoomPreset::TrustedPrivateChat), - }); - - let response = self.send(request, None).await?; - - // Now we need to mark the room as a DM for ourselves, we fetch the - // existing `m.direct` event and append the room to the list of DMs we - // have with this user. - let mut content = self - .account() - .account_data::() - .await? - .map(|c| c.deserialize()) - .transpose()? - .unwrap_or_default(); - - content.entry(user_id.to_owned()).or_default().push(response.room_id.to_owned()); - - // TODO We should probably save the fact that we need to send this out - // because otherwise we might end up in a state where we have a DM that - // isn't marked as one. - self.account().set_account_data(content).await?; - - // If the room is already in our store, fetch it, otherwise wait for a - // sync to be done which should put the room into our store. - if let Some(room) = self.get_joined_room(&response.room_id) { - Ok(Some(room)) - } else { - self.inner.sync_beat.listen().wait_timeout(SYNC_WAIT_TIME); - Ok(self.get_joined_room(&response.room_id)) - } - } - /// Claim one-time keys creating new Olm sessions. /// /// # Arguments diff --git a/crates/matrix-sdk/src/event_handler/mod.rs b/crates/matrix-sdk/src/event_handler/mod.rs index 045f729fa..22fb905f0 100644 --- a/crates/matrix-sdk/src/event_handler/mod.rs +++ b/crates/matrix-sdk/src/event_handler/mod.rs @@ -388,7 +388,7 @@ impl Client { None => (HandlerKind::MessageLike, HandlerKind::message_like_redacted(redacted)), }; - let raw_event = &item.event.json(); + let raw_event = item.event.json(); let encryption_info = item.encryption_info.as_ref(); // Event handlers for possibly-redacted timeline events diff --git a/crates/matrix-sdk/src/lib.rs b/crates/matrix-sdk/src/lib.rs index 225672330..2d18f48ca 100644 --- a/crates/matrix-sdk/src/lib.rs +++ b/crates/matrix-sdk/src/lib.rs @@ -55,3 +55,13 @@ pub use media::Media; #[cfg(test)] mod test_utils; + +#[cfg(all(test, not(target_arch = "wasm32")))] +#[ctor::ctor] +fn init_logging() { + use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; + tracing_subscriber::registry() + .with(tracing_subscriber::EnvFilter::from_default_env()) + .with(tracing_subscriber::fmt::layer().with_test_writer()) + .init(); +} diff --git a/crates/matrix-sdk/src/room/common.rs b/crates/matrix-sdk/src/room/common.rs index 1d01b20a9..47d3116c9 100644 --- a/crates/matrix-sdk/src/room/common.rs +++ b/crates/matrix-sdk/src/room/common.rs @@ -46,7 +46,8 @@ use ruma::{ SyncStateEvent, }, serde::Raw, - uint, EventId, MatrixToUri, MatrixUri, OwnedEventId, OwnedServerName, RoomId, UInt, UserId, + uint, EventId, MatrixToUri, MatrixUri, MilliSecondsSinceUnixEpoch, OwnedEventId, + OwnedServerName, RoomId, UInt, UserId, }; use serde::de::DeserializeOwned; use tracing::{debug, warn}; @@ -108,7 +109,7 @@ impl Common { /// /// Returns a [`Result`] containing an instance of [`Left`] if successful. /// - /// Only invited and joined rooms can be left + /// Only invited and joined rooms can be left. #[doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/docs/sync_running.md"))] pub(crate) async fn leave(&self) -> Result { let request = leave_room::v3::Request::new(self.inner.room_id()); @@ -117,6 +118,7 @@ impl Common { let user_id = self.client.user_id().ok_or(Error::AuthenticationRequired)?.to_owned(); + let now = MilliSecondsSinceUnixEpoch::now(); let handle = self.add_event_handler({ move |event: SyncStateEvent, room: Room| { let mut tx = tx.clone(); @@ -125,6 +127,7 @@ impl Common { async move { if *event.membership() == MembershipState::Leave && *event.state_key() == user_id + && event.origin_server_ts() > now { debug!("received RoomMemberEvent corresponding to requested leave"); @@ -153,14 +156,14 @@ impl Common { let option = TryStreamExt::try_next(&mut rx).await?; - Ok(option.expect("receive joined room result from event handler")) + Ok(option.expect("receive left room result from event handler")) } /// Join this room. /// /// Returns a [`Result`] containing an instance of [`Joined`][room::Joined] /// if successful. - /// Only invited and left rooms can be joined via this method + /// Only invited and left rooms can be joined via this method. #[doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/docs/sync_running.md"))] pub(crate) async fn join(&self) -> Result { self.client.join_room_by_id(self.room_id()).await @@ -583,7 +586,9 @@ impl Common { if let Some(mutex) = self.client.inner.members_request_locks.get(self.inner.room_id()).map(|m| m.clone()) { - mutex.lock().await; + // If a member request is already going on, await the release of + // the lock. + _ = mutex.lock().await; Ok(None) } else { diff --git a/crates/matrix-sdk/src/room/joined.rs b/crates/matrix-sdk/src/room/joined.rs index d4c91d7fd..dec1cd8ce 100644 --- a/crates/matrix-sdk/src/room/joined.rs +++ b/crates/matrix-sdk/src/room/joined.rs @@ -325,9 +325,9 @@ impl Joined { if let Some(mutex) = self.client.inner.group_session_locks.get(self.inner.room_id()).map(|m| m.clone()) { - // If a group session share request is already going on, - // await the release of the lock. - mutex.lock().await; + // If a group session share request is already going on, await the + // release of the lock. + _ = mutex.lock().await; } else { // Otherwise create a new lock and share the group // session. diff --git a/testing/matrix-sdk-integration-testing/Cargo.toml b/testing/matrix-sdk-integration-testing/Cargo.toml index 1085d0af4..eb1a21d6b 100644 --- a/testing/matrix-sdk-integration-testing/Cargo.toml +++ b/testing/matrix-sdk-integration-testing/Cargo.toml @@ -8,7 +8,9 @@ publish = false [dev-dependencies] anyhow = "1" assign = "1" +ctor = "0.1.23" matrix-sdk = { path = "../../crates/matrix-sdk" } once_cell = "1.13.0" tempfile = "3.3.0" tokio = { version = "1", features = ["rt", "rt-multi-thread", "macros"] } +tracing-subscriber = { version = "0.3.15", features = ["env-filter"] } diff --git a/testing/matrix-sdk-integration-testing/assets/ci-start.sh b/testing/matrix-sdk-integration-testing/assets/ci-start.sh index 6f717938d..cce1ff4bd 100644 --- a/testing/matrix-sdk-integration-testing/assets/ci-start.sh +++ b/testing/matrix-sdk-integration-testing/assets/ci-start.sh @@ -5,9 +5,9 @@ export SYNAPSE_REPORT_STATS=no echo " ====== Generating config ====== " /start.py generate echo " ====== Patching for CI ====== " -sed -i 's/^#enable_registration_without_verification:.*$/enable_registration_without_verification: true/g' /data/homeserver.yaml -sed -i 's/^#enable_registration:.*$/enable_registration: true/g' /data/homeserver.yaml echo """ +enable_registration: true +enable_registration_without_verification: true rc_message: per_second: 1000 @@ -16,6 +16,22 @@ rc_message: rc_registration: per_second: 1000 burst_count: 1000 + +rc_joins: + local: + per_second: 1000 + burst_count: 1000 + +rc_invites: + per_room: + per_second: 1000 + burst_count: 1000 + per_user: + per_second: 1000 + burst_count: 1000 + per_issuer: + per_second: 1000 + burst_count: 1000 rc_login: address: diff --git a/testing/matrix-sdk-integration-testing/src/tests.rs b/testing/matrix-sdk-integration-testing/src/tests.rs index 43e9d62be..147daf857 100644 --- a/testing/matrix-sdk-integration-testing/src/tests.rs +++ b/testing/matrix-sdk-integration-testing/src/tests.rs @@ -3,8 +3,8 @@ use std::{collections::HashMap, option_env}; use anyhow::Result; use assign::assign; use matrix_sdk::{ + config::RequestConfig, ruma::api::client::{account::register::v3::Request as RegistrationRequest, uiaa}, - store::make_store_config, Client, }; use once_cell::sync::Lazy; @@ -13,6 +13,15 @@ use tokio::sync::Mutex; static USERS: Lazy>> = Lazy::new(Mutex::default); +#[ctor::ctor] +fn init_logging() { + use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; + tracing_subscriber::registry() + .with(tracing_subscriber::EnvFilter::from_default_env()) + .with(tracing_subscriber::fmt::layer().with_test_writer()) + .init(); +} + /// read the test configuration from the environment pub fn test_server_conf() -> (String, String) { ( @@ -21,7 +30,14 @@ pub fn test_server_conf() -> (String, String) { ) } -pub async fn get_client_for_user(username: String) -> Result { +/// The StateStore to use. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum Store { + Memory, + Sled, +} + +pub async fn get_client_for_user(store: Store, username: String) -> Result { let mut users = USERS.lock().await; if let Some((client, _)) = users.get(&username) { return Ok(client.clone()); @@ -31,12 +47,15 @@ pub async fn get_client_for_user(username: String) -> Result { let tmp_dir = tempdir()?; - let client = Client::builder() + let mut builder = Client::builder() .user_agent("matrix-sdk-integation-tests") - .store_config(make_store_config(tmp_dir.path(), None)?) .homeserver_url(homeserver_url) - .build() - .await?; + .request_config(RequestConfig::new().disable_retry()); + builder = match store { + Store::Memory => builder, + Store::Sled => builder.sled_store(tmp_dir.path(), None)?, + }; + let client = builder.build().await?; // safe to assume we have not registered this user yet, but ignore if we did if let Err(resp) = client.register(RegistrationRequest::new()).await { @@ -59,3 +78,4 @@ pub async fn get_client_for_user(username: String) -> Result { } mod invitations; +mod repeated_join; diff --git a/testing/matrix-sdk-integration-testing/src/tests/invitations.rs b/testing/matrix-sdk-integration-testing/src/tests/invitations.rs index 14244943f..772a69f4a 100644 --- a/testing/matrix-sdk-integration-testing/src/tests/invitations.rs +++ b/testing/matrix-sdk-integration-testing/src/tests/invitations.rs @@ -6,12 +6,12 @@ use matrix_sdk::{ room::Room, ruma::api::client::room::create_room::v3::Request as CreateRoomRequest, }; -use super::get_client_for_user; +use super::{get_client_for_user, Store}; #[tokio::test(flavor = "multi_thread", worker_threads = 4)] async fn test_invitation_details() -> Result<()> { - let tamatoa = get_client_for_user("tamatoa".to_owned()).await?; - let sebastian = get_client_for_user("sebastian".to_owned()).await?; + let tamatoa = get_client_for_user(Store::Sled, "tamatoa".to_owned()).await?; + let sebastian = get_client_for_user(Store::Sled, "sebastian".to_owned()).await?; let invites = [sebastian.user_id().expect("sebastian has a userid!").to_owned()]; // create a room and invite sebastian; diff --git a/testing/matrix-sdk-integration-testing/src/tests/repeated_join.rs b/testing/matrix-sdk-integration-testing/src/tests/repeated_join.rs new file mode 100644 index 000000000..7d918c7f7 --- /dev/null +++ b/testing/matrix-sdk-integration-testing/src/tests/repeated_join.rs @@ -0,0 +1,144 @@ +use std::time::Duration; + +use anyhow::Result; +use assign::assign; +use matrix_sdk::{ + event_handler::Ctx, + room::Room, + ruma::{ + api::client::room::create_room::v3::Request as CreateRoomRequest, + events::room::member::{MembershipState, StrippedRoomMemberEvent}, + }, + Client, RoomType, +}; +use tokio::sync::mpsc; + +use super::{get_client_for_user, Store}; + +#[tokio::test(flavor = "multi_thread", worker_threads = 4)] +async fn test_repeated_join_leave() -> Result<()> { + let peter = get_client_for_user(Store::Memory, "peter".to_owned()).await?; + // FIXME: Run once with memory, once with sled + let karl = get_client_for_user(Store::Sled, "karl".to_owned()).await?; + let karl_id = karl.user_id().expect("karl has a userid!").to_owned(); + + // Create a room and invite karl. + let invites = [karl_id.clone()]; + let request = assign!(CreateRoomRequest::new(), { + invite: &invites, + is_direct: true, + }); + + // Sync after 1 second to so that create_room receives the event it is waiting + // for. + let peter_clone = peter.clone(); + tokio::spawn(async move { + tokio::time::sleep(Duration::from_secs(1)).await; + peter_clone.sync_once(Default::default()).await + }); + + let created_room = peter.create_room(request).await?; + let room_id = created_room.room_id(); + + // Sync karl once to ensure he got the invite. + karl.sync_once(Default::default()).await?; + + // Continuously sync karl from now on. + let karl_clone = karl.clone(); + let join_handle = tokio::spawn(async move { + karl_clone.sync(Default::default()).await; + }); + let (invite_signal_sender, mut invite_signal) = mpsc::channel::<()>(1); + karl.add_event_handler_context(invite_signal_sender); + karl.add_event_handler(signal_on_invite); + + for i in 0..3 { + println!("Iteration {i}"); + + // Test that karl has the expected state in its client. + assert!(karl.get_invited_room(room_id).is_some()); + assert!(karl.get_joined_room(room_id).is_none()); + assert!(karl.get_left_room(room_id).is_none()); + + let room = karl.get_room(room_id).expect("karl has the room"); + let membership = room.get_member_no_sync(&karl_id).await?.expect("karl was invited"); + assert_eq!(*membership.membership(), MembershipState::Invite); + + // Join the room + println!("Joining.."); + let room = + karl.get_invited_room(room_id).expect("karl has the room").accept_invitation().await?; + println!("Done"); + let membership = room.get_member_no_sync(&karl_id).await?.expect("karl joined"); + assert_eq!(*membership.membership(), MembershipState::Join); + + assert!(karl.get_invited_room(room_id).is_none()); + assert!(karl.get_joined_room(room_id).is_some()); + assert!(karl.get_left_room(room_id).is_none()); + + // Leave the room + println!("Leaving.."); + let room = room.leave().await?; + println!("Done"); + let membership = room.get_member_no_sync(&karl_id).await?.expect("karl left"); + assert_eq!(*membership.membership(), MembershipState::Leave); + + assert!(karl.get_invited_room(room_id).is_none()); + assert!(karl.get_joined_room(room_id).is_none()); + assert!(karl.get_left_room(room_id).is_some()); + + // Invite karl again and wait for karl to receive the invite. + println!("Inviting.."); + let room = peter.get_joined_room(room_id).expect("peter created the room!"); + room.invite_user_by_id(&karl_id).await?; + println!("Waiting to receive invite.."); + invite_signal.recv().await.expect("sender must be open"); + } + + // Stop the sync. + join_handle.abort(); + + // Now check the underlying state store that it also has the correct information + // (for when the client restarts). + let invited = karl.store().get_invited_user_ids(room_id).await?; + assert_eq!(invited.len(), 1); + assert_eq!(invited[0], karl_id); + + let joined = karl.store().get_joined_user_ids(room_id).await?; + assert!(!joined.contains(&karl_id)); + + let event = + karl.store().get_member_event(room_id, &karl_id).await?.expect("member event should exist"); + assert_eq!(*event.membership(), MembershipState::Invite); + + // Yay, test succeeded + Ok(()) +} + +async fn signal_on_invite( + event: StrippedRoomMemberEvent, + room: Room, + client: Client, + sender: Ctx>, +) { + let own_id = client.user_id().expect("client is logged in"); + if event.sender == own_id { + return; + } + + if room.room_type() != RoomType::Invited { + return; + } + + if event.content.membership != MembershipState::Invite { + return; + } + + let invited = &event.state_key; + if invited != own_id { + return; + } + + // Send signal that we received an invite. + sender.send(()).await.expect("receiver must be open"); +} diff --git a/testing/matrix-sdk-test/src/test_json/sync.rs b/testing/matrix-sdk-test/src/test_json/sync.rs index fdf4c9cf3..db2dc7e25 100644 --- a/testing/matrix-sdk-test/src/test_json/sync.rs +++ b/testing/matrix-sdk-test/src/test_json/sync.rs @@ -70,7 +70,7 @@ pub static SYNC: Lazy = Lazy::new(|| { "join_rule": "public" }, "event_id": "$15139375514WsgmR:localhost", - "origin_server_ts": 151393755, + "origin_server_ts": 151393755000000_u64, "sender": "@example:localhost", "state_key": "", "type": "m.room.join_rules", @@ -86,7 +86,7 @@ pub static SYNC: Lazy = Lazy::new(|| { }, "event_id": "$151800140517rfvjc:localhost", "membership": "join", - "origin_server_ts": 151800140, + "origin_server_ts": 151800140000000_u64, "sender": "@example:localhost", "state_key": "@example:localhost", "type": "m.room.member", @@ -100,7 +100,7 @@ pub static SYNC: Lazy = Lazy::new(|| { "history_visibility": "shared" }, "event_id": "$15139375515VaJEY:localhost", - "origin_server_ts": 151393755, + "origin_server_ts": 151393755000000_u64, "sender": "@example:localhost", "state_key": "", "type": "m.room.history_visibility", @@ -113,7 +113,7 @@ pub static SYNC: Lazy = Lazy::new(|| { "creator": "@example:localhost" }, "event_id": "$15139375510KUZHi:localhost", - "origin_server_ts": 151393755, + "origin_server_ts": 151393755000000_u64, "sender": "@example:localhost", "state_key": "", "type": "m.room.create", @@ -128,7 +128,7 @@ pub static SYNC: Lazy = Lazy::new(|| { ] }, "event_id": "$15139375516NUgtD:localhost", - "origin_server_ts": 151393755, + "origin_server_ts": 151393755000000_u64, "sender": "@example:localhost", "state_key": "localhost", "type": "m.room.aliases", @@ -141,7 +141,7 @@ pub static SYNC: Lazy = Lazy::new(|| { "topic": "room topic" }, "event_id": "$151957878228ssqrJ:localhost", - "origin_server_ts": 151957878, + "origin_server_ts": 151957878000000_u64, "sender": "@example:localhost", "state_key": "", "type": "m.room.topic", @@ -175,7 +175,7 @@ pub static SYNC: Lazy = Lazy::new(|| { "users_default": 0 }, "event_id": "$15139375512JaHAW:localhost", - "origin_server_ts": 151393755, + "origin_server_ts": 151393755000000_u64, "sender": "@example:localhost", "state_key": "", "type": "m.room.power_levels", @@ -188,7 +188,7 @@ pub static SYNC: Lazy = Lazy::new(|| { "alias": "#tutorial:localhost" }, "event_id": "$15139375513VdeRF:localhost", - "origin_server_ts": 151393755, + "origin_server_ts": 151393755000000_u64, "sender": "@example:localhost", "state_key": "", "type": "m.room.canonical_alias", @@ -204,7 +204,7 @@ pub static SYNC: Lazy = Lazy::new(|| { }, "event_id": "$152034824468gOeNB:localhost", "membership": "join", - "origin_server_ts": 152034824, + "origin_server_ts": 152034824000000_u64, "sender": "@example2:localhost", "state_key": "@example2:localhost", "type": "m.room.member", @@ -229,7 +229,7 @@ pub static SYNC: Lazy = Lazy::new(|| { "msgtype": "m.text" }, "event_id": "$152037280074GZeOm:localhost", - "origin_server_ts": 152037280, + "origin_server_ts": 152037280000000_u64, "sender": "@example:localhost", "type": "m.room.message", "unsigned": { @@ -332,7 +332,7 @@ pub static DEFAULT_SYNC_SUMMARY: Lazy = Lazy::new(|| { "join_rule": "public" }, "event_id": "$15139375514WsgmR:localhost", - "origin_server_ts": 151393755, + "origin_server_ts": 151393755000000_u64, "sender": "@example:localhost", "state_key": "", "type": "m.room.join_rules", @@ -348,7 +348,7 @@ pub static DEFAULT_SYNC_SUMMARY: Lazy = Lazy::new(|| { }, "event_id": "$151800140517rfvjc:localhost", "membership": "join", - "origin_server_ts": 151800140, + "origin_server_ts": 151800140000000_u64, "sender": "@example:localhost", "state_key": "@example:localhost", "type": "m.room.member", @@ -362,7 +362,7 @@ pub static DEFAULT_SYNC_SUMMARY: Lazy = Lazy::new(|| { "history_visibility": "shared" }, "event_id": "$15139375515VaJEY:localhost", - "origin_server_ts": 151393755, + "origin_server_ts": 151393755000000_u64, "sender": "@example:localhost", "state_key": "", "type": "m.room.history_visibility", @@ -375,7 +375,7 @@ pub static DEFAULT_SYNC_SUMMARY: Lazy = Lazy::new(|| { "creator": "@example:localhost" }, "event_id": "$15139375510KUZHi:localhost", - "origin_server_ts": 151393755, + "origin_server_ts": 151393755000000_u64, "sender": "@example:localhost", "state_key": "", "type": "m.room.create", @@ -388,7 +388,7 @@ pub static DEFAULT_SYNC_SUMMARY: Lazy = Lazy::new(|| { "topic": "room topic" }, "event_id": "$151957878228ssqrJ:localhost", - "origin_server_ts": 151957878, + "origin_server_ts": 151957878000000_u64, "sender": "@example:localhost", "state_key": "", "type": "m.room.topic", @@ -422,7 +422,7 @@ pub static DEFAULT_SYNC_SUMMARY: Lazy = Lazy::new(|| { "users_default": 0 }, "event_id": "$15139375512JaHAW:localhost", - "origin_server_ts": 151393755, + "origin_server_ts": 151393755000000_u64, "sender": "@example:localhost", "state_key": "", "type": "m.room.power_levels", @@ -438,7 +438,7 @@ pub static DEFAULT_SYNC_SUMMARY: Lazy = Lazy::new(|| { }, "event_id": "$152034824468gOeNB:localhost", "membership": "join", - "origin_server_ts": 152034824, + "origin_server_ts": 152034824000000_u64, "sender": "@example2:localhost", "state_key": "@example2:localhost", "type": "m.room.member", @@ -459,7 +459,7 @@ pub static DEFAULT_SYNC_SUMMARY: Lazy = Lazy::new(|| { "displayname": "example" }, "event_id": "$1585345508297748AIUBh:matrix.org", - "origin_server_ts": 158534550, + "origin_server_ts": 158534550000000_u64, "sender": "@example:localhost", "state_key": "@example:localhost", "type": "m.room.member", @@ -487,7 +487,7 @@ pub static DEFAULT_SYNC_SUMMARY: Lazy = Lazy::new(|| { "msgtype": "m.text" }, "event_id": "$152037280074GZeOm:localhost", - "origin_server_ts": 152037280, + "origin_server_ts": 152037280000000_u64, "sender": "@example:localhost", "type": "m.room.message", "unsigned": { @@ -585,7 +585,7 @@ pub static MORE_SYNC: Lazy = Lazy::new(|| { "msgtype": "m.text" }, "event_id": "$152037280074GZeOm:localhost", - "origin_server_ts": 152037280, + "origin_server_ts": 152037280000000_u64, "sender": "@example:localhost", "type": "m.room.message", "unsigned": { @@ -606,7 +606,7 @@ pub static MORE_SYNC: Lazy = Lazy::new(|| { "msgtype": "m.text" }, "event_id": "$editevid:localhost", - "origin_server_ts": 159026265, + "origin_server_ts": 159026265000000_u64, "sender": "@alice:matrix.org", "type": "m.room.message", "unsigned": { @@ -618,7 +618,7 @@ pub static MORE_SYNC: Lazy = Lazy::new(|| { "reason": "😀" }, "event_id": "$151957878228ssqrJ:localhost", - "origin_server_ts": 151957878, + "origin_server_ts": 151957878000000_u64, "sender": "@example:localhost", "type": "m.room.redaction", "redacts": "$151957878228ssqrj:localhost", @@ -629,7 +629,7 @@ pub static MORE_SYNC: Lazy = Lazy::new(|| { { "content": {}, "event_id": "$15275046980maRLj:localhost", - "origin_server_ts": 152750469, + "origin_server_ts": 152750469000000_u64, "sender": "@example:localhost", "type": "m.room.message", "unsigned": { @@ -637,7 +637,7 @@ pub static MORE_SYNC: Lazy = Lazy::new(|| { "redacted_because": { "content": {}, "event_id": "$15275047031IXQRi:localhost", - "origin_server_ts": 152750470, + "origin_server_ts": 152750470000000_u64, "redacts": "$15275046980maRLj:localhost", "sender": "@example:localhost", "type": "m.room.redaction", @@ -657,7 +657,7 @@ pub static MORE_SYNC: Lazy = Lazy::new(|| { } }, "event_id": "$15275047031IXQRi:localhost", - "origin_server_ts": 159027581, + "origin_server_ts": 159027581000000_u64, "sender": "@alice:matrix.org", "type": "m.reaction", "unsigned": { @@ -672,7 +672,7 @@ pub static MORE_SYNC: Lazy = Lazy::new(|| { "msgtype": "m.notice" }, "event_id": "$098237280074GZeOm:localhost", - "origin_server_ts": 162037280, + "origin_server_ts": 162037280000000_u64, "sender": "@bot:localhost", "type": "m.room.message", "unsigned": { @@ -716,7 +716,7 @@ pub static MORE_SYNC_2: Lazy = Lazy::new(|| { "msgtype": "m.text" }, "event_id": "$152037280074GZeOm2:localhost", - "origin_server_ts": 152037280, + "origin_server_ts": 152037280000000_u64, "sender": "@example:localhost", "type": "m.room.message", "unsigned": { @@ -737,7 +737,7 @@ pub static MORE_SYNC_2: Lazy = Lazy::new(|| { "msgtype": "m.text" }, "event_id": "$editevid2:localhost", - "origin_server_ts": 159026265, + "origin_server_ts": 159026265000000_u64, "sender": "@alice:matrix.org", "type": "m.room.message", "unsigned": { @@ -749,7 +749,7 @@ pub static MORE_SYNC_2: Lazy = Lazy::new(|| { "reason": "😀" }, "event_id": "$151957878228ssqrJ2:localhost", - "origin_server_ts": 151957878, + "origin_server_ts": 151957878000000_u64, "sender": "@example:localhost", "type": "m.room.redaction", "redacts": "$151957878228ssqrj:localhost", @@ -760,7 +760,7 @@ pub static MORE_SYNC_2: Lazy = Lazy::new(|| { { "content": {}, "event_id": "$15275046980maRLj2:localhost", - "origin_server_ts": 152750469, + "origin_server_ts": 152750469000000_u64, "sender": "@example:localhost", "type": "m.room.message", "unsigned": { @@ -768,7 +768,7 @@ pub static MORE_SYNC_2: Lazy = Lazy::new(|| { "redacted_because": { "content": {}, "event_id": "$15275047031IXQRi:localhost", - "origin_server_ts": 152750470, + "origin_server_ts": 152750470000000_u64, "redacts": "$15275046980maRLj:localhost", "sender": "@example:localhost", "type": "m.room.redaction", @@ -788,7 +788,7 @@ pub static MORE_SYNC_2: Lazy = Lazy::new(|| { } }, "event_id": "$15275047031IXQRi2:localhost", - "origin_server_ts": 159027581, + "origin_server_ts": 159027581000000_u64, "sender": "@alice:matrix.org", "type": "m.reaction", "unsigned": { @@ -803,7 +803,7 @@ pub static MORE_SYNC_2: Lazy = Lazy::new(|| { "msgtype": "m.notice" }, "event_id": "$098237280074GZeOm2:localhost", - "origin_server_ts": 162037280, + "origin_server_ts": 162037280000000_u64, "sender": "@bot:localhost", "type": "m.room.message", "unsigned": { @@ -944,7 +944,7 @@ pub static LEAVE_SYNC: Lazy = Lazy::new(|| { "join_rule": "public" }, "event_id": "$15139375514WsgmR:localhost", - "origin_server_ts": 151393755, + "origin_server_ts": 151393755000000_u64, "sender": "@example:localhost", "state_key": "", "type": "m.room.join_rules", @@ -960,7 +960,7 @@ pub static LEAVE_SYNC: Lazy = Lazy::new(|| { }, "event_id": "$151800140517rfvjc:localhost", "membership": "join", - "origin_server_ts": 151800140, + "origin_server_ts": 151800140000000_u64, "sender": "@example:localhost", "state_key": "@example:localhost", "type": "m.room.member", @@ -974,7 +974,7 @@ pub static LEAVE_SYNC: Lazy = Lazy::new(|| { "history_visibility": "shared" }, "event_id": "$15139375515VaJEY:localhost", - "origin_server_ts": 151393755, + "origin_server_ts": 151393755000000_u64, "sender": "@example:localhost", "state_key": "", "type": "m.room.history_visibility", @@ -987,7 +987,7 @@ pub static LEAVE_SYNC: Lazy = Lazy::new(|| { "creator": "@example:localhost" }, "event_id": "$15139375510KUZHi:localhost", - "origin_server_ts": 151393755, + "origin_server_ts": 151393755000000_u64, "sender": "@example:localhost", "state_key": "", "type": "m.room.create", @@ -1002,7 +1002,7 @@ pub static LEAVE_SYNC: Lazy = Lazy::new(|| { ] }, "event_id": "$15139375516NUgtD:localhost", - "origin_server_ts": 151393755, + "origin_server_ts": 151393755000000_u64, "sender": "@example:localhost", "state_key": "localhost", "type": "m.room.aliases", @@ -1015,7 +1015,7 @@ pub static LEAVE_SYNC: Lazy = Lazy::new(|| { "topic": "room topic" }, "event_id": "$151957878228ssqrJ:localhost", - "origin_server_ts": 151957878, + "origin_server_ts": 151957878000000_u64, "sender": "@example:localhost", "state_key": "", "type": "m.room.topic", @@ -1049,7 +1049,7 @@ pub static LEAVE_SYNC: Lazy = Lazy::new(|| { "users_default": 0 }, "event_id": "$15139375512JaHAW:localhost", - "origin_server_ts": 151393755, + "origin_server_ts": 151393755000000_u64, "sender": "@example:localhost", "state_key": "", "type": "m.room.power_levels", @@ -1062,7 +1062,7 @@ pub static LEAVE_SYNC: Lazy = Lazy::new(|| { "alias": "#tutorial:localhost" }, "event_id": "$15139375513VdeRF:localhost", - "origin_server_ts": 151393755, + "origin_server_ts": 151393755000000_u64, "sender": "@example:localhost", "state_key": "", "type": "m.room.canonical_alias", @@ -1078,7 +1078,7 @@ pub static LEAVE_SYNC: Lazy = Lazy::new(|| { }, "event_id": "$152034824468gOeNB:localhost", "membership": "join", - "origin_server_ts": 152034824, + "origin_server_ts": 152034824000000_u64, "sender": "@example2:localhost", "state_key": "@example2:localhost", "type": "m.room.member", @@ -1099,7 +1099,7 @@ pub static LEAVE_SYNC: Lazy = Lazy::new(|| { "displayname": "example" }, "event_id": "$1585345508297748AIUBh:matrix.org", - "origin_server_ts": 158534550, + "origin_server_ts": 158534550000000_u64, "sender": "@example:localhost", "state_key": "@example:localhost", "type": "m.room.member", @@ -1127,7 +1127,7 @@ pub static LEAVE_SYNC: Lazy = Lazy::new(|| { "msgtype": "m.text" }, "event_id": "$152037280074GZeOm:localhost", - "origin_server_ts": 152037280, + "origin_server_ts": 152037280000000_u64, "sender": "@example:localhost", "type": "m.room.message", "unsigned": { @@ -1192,7 +1192,7 @@ pub static LEAVE_SYNC_EVENT: Lazy = Lazy::new(|| { "content": { "membership": "leave" }, - "origin_server_ts": 158957809, + "origin_server_ts": 158957809000000_u64, "sender": "@example:localhost", "state_key": "@example:localhost", "type": "m.room.member", @@ -1270,7 +1270,7 @@ pub static VOIP_SYNC: Lazy = Lazy::new(|| { "version": 0 }, "event_id": "$143273582443PhrSn:example.org", - "origin_server_ts": 143273582, + "origin_server_ts": 143273582000000_u64, "room_id": "!jEsUZKDJdhlrceRyVU:example.org", "sender": "@example:example.org", "type": "m.call.invite", @@ -1289,7 +1289,7 @@ pub static VOIP_SYNC: Lazy = Lazy::new(|| { "version": 0 }, "event_id": "$143273582443PhrSn:example.org", - "origin_server_ts": 143273582, + "origin_server_ts": 143273582000000_u64, "room_id": "!jEsUZKDJdhlrceRyVU:example.org", "sender": "@example:example.org", "type": "m.call.answer", @@ -1310,7 +1310,7 @@ pub static VOIP_SYNC: Lazy = Lazy::new(|| { "version": 0 }, "event_id": "$143273582443PhrSn:example.org", - "origin_server_ts": 143273582, + "origin_server_ts": 143273582000000_u64, "room_id": "!jEsUZKDJdhlrceRyVU:example.org", "sender": "@example:example.org", "type": "m.call.candidates", @@ -1324,7 +1324,7 @@ pub static VOIP_SYNC: Lazy = Lazy::new(|| { "version": 0 }, "event_id": "$143273582443PhrSn:example.org", - "origin_server_ts": 143273582, + "origin_server_ts": 143273582000000_u64, "room_id": "!jEsUZKDJdhlrceRyVU:example.org", "sender": "@example:example.org", "type": "m.call.hangup",