@@ -426,6 +426,8 @@ func TestReverseTopologicalEventSorting(t *testing.T) {
426426 }
427427}
428428
429+ func isRejectedTest (_ string ) bool { return false }
430+
429431func TestStateResolutionOtherEventDoesntOverpowerPowerEvent (t * testing.T ) {
430432 eventJSONs := []string {
431433 /* create event */ `{"auth_events":[],"content":{"creator":"@anon-20220512_124253-1:localhost:8800","room_version":"6"},"depth":1,"hashes":{"sha256":"ej3MHt4EnQemwqnfLhgwN6RBArYc5JnWcZt1PI3m4hE"},"origin":"localhost:8800","origin_server_ts":1652359375504,"prev_events":[],"prev_state":[],"room_id":"!3CHu7khd0phWyTm5:localhost:8800","sender":"@anon-20220512_124253-1:localhost:8800","signatures":{"localhost:8800":{"ed25519:rhNBRg":"7Pu9f39yDWJtl8msrnz+sPSBEA2jOJ4tJsZ1Zb6Bi+vZQMzMWwT/U6GZipxQqaeJr0TpVMa7zq/YhivArRRbAA"}},"state_key":"","type":"m.room.create"}` ,
@@ -463,6 +465,7 @@ func TestStateResolutionOtherEventDoesntOverpowerPowerEvent(t *testing.T) {
463465 unconflicted , // unconflicted set
464466 events , // full auth set
465467 UserIDForSenderTest ,
468+ isRejectedTest ,
466469 )
467470 t .Log ("Resolved:" )
468471 for k , v := range result {
@@ -489,6 +492,7 @@ func runStateResolutionV2(t *testing.T, additional []PDU, expected []string) {
489492 unconflicted , // unconflicted set
490493 input , // full auth set
491494 UserIDForSenderTest ,
495+ isRejectedTest ,
492496 )
493497
494498 t .Log ("Result:" )
@@ -571,7 +575,68 @@ func TestStateReset(t *testing.T) {
571575 "$IaXTO8US6DmRrPexxTucUaMoc7M0uwvMrOzWoFSsy5o" : jr2Ev ,
572576 }
573577
574- resolved := ResolveStateConflictsV2 (conflicted , unconflicted , authEvents , UserIDForSenderTest )
578+ resolved := ResolveStateConflictsV2 (conflicted , unconflicted , authEvents , UserIDForSenderTest , isRejectedTest )
579+ unexpectedEvents := make (map [string ]PDU )
580+ for _ , resolvedEv := range resolved {
581+ if _ , found := expectedEvents [resolvedEv .EventID ()]; ! found {
582+ unexpectedEvents [resolvedEv .EventID ()] = resolvedEv
583+ continue
584+ }
585+ delete (expectedEvents , resolvedEv .EventID ())
586+ }
587+
588+ if len (expectedEvents ) > 0 {
589+ t .Error ("Expected event missing after state resolution:" )
590+ for evID , ev := range expectedEvents {
591+ t .Errorf ("\t %s: %s" , evID , ev .JSON ())
592+ }
593+ }
594+
595+ if len (unexpectedEvents ) > 0 {
596+ t .Error ("Unexpected events after state resolution:" )
597+ for evID , ev := range unexpectedEvents {
598+ t .Errorf ("\t %s: %s" , evID , ev .JSON ())
599+ }
600+ }
601+ }
602+
603+ // Basically copy and paste of TestStateReset, with the difference
604+ // that the join event of Bob (bobJoinEv) is rejected when authing
605+ // the name change event. This results in Bob not being in the room.
606+ func TestStateResetWithRejectedJoin (t * testing.T ) {
607+ // NOTE: The following events are taken from a Dendrite UT.
608+ createEv := mustParseEvent (t , []byte (`{"auth_events":[],"content":{"creator":"@1:test","room_version":"9"},"depth":1,"hashes":{"sha256":"OZriBeMNVoymY/JqjM3Ee6oKSfoWskCiy48dUq5crR8"},"origin":"test","origin_server_ts":1697134517143,"prev_events":[],"prev_state":[],"room_id":"!2:test","sender":"@1:test","signatures":{"test":{"ed25519:test":"eyVzDAWjFtEaDtcYD2aLOjwxYegJSRJTEg5eRkksL3rNJUB0nRim2iGGCznjNzTg3V84K4bmuIs41aR7A2TBBQ"}},"state_key":"","type":"m.room.create"}` ))
609+ aliceJoinEv := mustParseEvent (t , []byte (`{"auth_events":["$0B4FVZWbziXiuaBZyVerHDfBs40toK4FhoT1DNLs_tg"],"content":{"membership":"join"},"depth":2,"hashes":{"sha256":"xktNmFYn936RCil8B5h5Jfb+BFuyCKfUsOHCU92KHbE"},"origin":"test","origin_server_ts":1697134517143,"prev_events":["$0B4FVZWbziXiuaBZyVerHDfBs40toK4FhoT1DNLs_tg"],"prev_state":[],"room_id":"!2:test","sender":"@1:test","signatures":{"test":{"ed25519:test":"cBaNa3UDzDE/TEH0ZmDciJj7aa5XOv8Ze1F+YGxea/TI86ivD6ULkylEl9+52A3kNC1/k8u7d7VZTDEMA/YZCw"}},"state_key":"@1:test","type":"m.room.member"}` ))
610+ plEv := mustParseEvent (t , []byte (`{"auth_events":["$0B4FVZWbziXiuaBZyVerHDfBs40toK4FhoT1DNLs_tg","$pha7iGLaAXqkf_GAwBhPtdyjM0DF4qxiAbbc-zGJbRc"],"content":{"ban":50,"events":{"m.room.avatar":50,"m.room.canonical_alias":50,"m.room.encryption":100,"m.room.history_visibility":100,"m.room.name":50,"m.room.power_levels":100,"m.room.server_acl":100,"m.room.tombstone":100},"events_default":0,"invite":0,"kick":50,"notifications":{"room":50},"redact":50,"state_default":50,"users":{"@1:test":100},"users_default":0},"depth":3,"hashes":{"sha256":"Tg8kVJh7Pam9Q9rkMa2qoPzkQ2febdBLGiB2dB+6aqQ"},"origin":"test","origin_server_ts":1697134517143,"prev_events":["$pha7iGLaAXqkf_GAwBhPtdyjM0DF4qxiAbbc-zGJbRc"],"prev_state":[],"room_id":"!2:test","sender":"@1:test","signatures":{"test":{"ed25519:test":"1BKFKdklWUkxeKn8+9lGUVRNYSTscFwP0JR6KPH/KvuqOdOOl896mIJ3lp9iLrrHFYEOP0+Tl/gWWjY0r4zoBA"}},"state_key":"","type":"m.room.power_levels"}` ))
611+ jrEv := mustParseEvent (t , []byte (`{"auth_events":["$0B4FVZWbziXiuaBZyVerHDfBs40toK4FhoT1DNLs_tg","$B6yTeN_9fWhp5duir471Ac-OSC9BlsHnlRcbVpfmOH0","$pha7iGLaAXqkf_GAwBhPtdyjM0DF4qxiAbbc-zGJbRc"],"content":{"join_rule":"public"},"depth":4,"hashes":{"sha256":"he+A0e/+4282sOZ0E6eXAGrQ7b2wAHfr4E/qMX2Sosg"},"origin":"test","origin_server_ts":1697134517144,"prev_events":["$B6yTeN_9fWhp5duir471Ac-OSC9BlsHnlRcbVpfmOH0"],"prev_state":[],"room_id":"!2:test","sender":"@1:test","signatures":{"test":{"ed25519:test":"tnX+YOaNhWipRTAsnXtxDeT0OLGQRhQN/cWF4cjLj92zjfyvGPIgoMXBpdFojq+0TiCsTPx673aWiYKFGap3AA"}},"state_key":"","type":"m.room.join_rules"}` ))
612+ hisVisEv := mustParseEvent (t , []byte (`{"auth_events":["$0B4FVZWbziXiuaBZyVerHDfBs40toK4FhoT1DNLs_tg","$B6yTeN_9fWhp5duir471Ac-OSC9BlsHnlRcbVpfmOH0","$pha7iGLaAXqkf_GAwBhPtdyjM0DF4qxiAbbc-zGJbRc"],"content":{"history_visibility":"shared"},"depth":5,"hashes":{"sha256":"keUaZvadB9S775FT2/WOog+XwqcquUMDLlsKjtx7HYI"},"origin":"test","origin_server_ts":1697134517144,"prev_events":["$ZDzKFnVFil6ea2QoMa5wpFW_RJe5kTEv2ZD4jctEWM4"],"prev_state":[],"room_id":"!2:test","sender":"@1:test","signatures":{"test":{"ed25519:test":"OX1cA63VvYy/xli+kzJqAy/0f20RKMxn8khqvWYry3bRQqXRN2Z+er3wMFo6dego9e37l1b4UWXnoFvAUYbaDA"}},"state_key":"","type":"m.room.history_visibility"}` ))
613+ bobJoinEv := mustParseEvent (t , []byte (`{"auth_events":["$0B4FVZWbziXiuaBZyVerHDfBs40toK4FhoT1DNLs_tg","$ZDzKFnVFil6ea2QoMa5wpFW_RJe5kTEv2ZD4jctEWM4","$B6yTeN_9fWhp5duir471Ac-OSC9BlsHnlRcbVpfmOH0"],"content":{"membership":"join"},"depth":6,"hashes":{"sha256":"eMAArXQGPaJMbU22Bvgqzks1zLMiQTGXI28eT4CsEaM"},"origin":"test","origin_server_ts":1697134517145,"prev_events":["$KvMXxqhECWclFe58hgxr_s26ytJ57olFSMv2uVjbtSo"],"prev_state":[],"room_id":"!2:test","sender":"@2:test","signatures":{"test":{"ed25519:test":"TT+NLaNGzJbEe2B9AZ1rPUX/Af3S7rHpZK2Vqv3ioxrH7pzs7nDSs2+1G9+yxxjqLtybi1QuFbyGKAb2J/DmDA"}},"state_key":"@2:test","type":"m.room.member"}` ))
614+ charlieJoinEv := mustParseEvent (t , []byte (`{"auth_events":["$0B4FVZWbziXiuaBZyVerHDfBs40toK4FhoT1DNLs_tg","$ZDzKFnVFil6ea2QoMa5wpFW_RJe5kTEv2ZD4jctEWM4","$B6yTeN_9fWhp5duir471Ac-OSC9BlsHnlRcbVpfmOH0"],"content":{"membership":"join"},"depth":7,"hashes":{"sha256":"lsD2HYq8ovMhfTznU4RH2vk/cZTa8nwQVM8LYyCTzZs"},"origin":"test","origin_server_ts":1697134517145,"prev_events":["$AbMj-EZa-blPfjNYj9dPUXAQM5oLxcnPdoUvtTVI-hs"],"prev_state":[],"room_id":"!2:test","sender":"@3:test","signatures":{"test":{"ed25519:test":"5wOjA9IZkN28/yd4bJl8elnsxGR9QjDzKhSxDq/Js24hnqErV0DRB4luETZZDTWdCJJPRy5q7mIOoCTr6Zv/DQ"}},"state_key":"@3:test","type":"m.room.member"}` ))
615+ bobNameEv := mustParseEvent (t , []byte (`{"auth_events":["$0B4FVZWbziXiuaBZyVerHDfBs40toK4FhoT1DNLs_tg","$ZDzKFnVFil6ea2QoMa5wpFW_RJe5kTEv2ZD4jctEWM4","$B6yTeN_9fWhp5duir471Ac-OSC9BlsHnlRcbVpfmOH0","$AbMj-EZa-blPfjNYj9dPUXAQM5oLxcnPdoUvtTVI-hs"],"content":{"displayname":"Bob!","membership":"join"},"depth":10,"hashes":{"sha256":"GKm317RAdHnrAnESQRocRS5DhSJ756/3UjxBskjKEz4"},"origin":"test","origin_server_ts":1697134517386,"prev_events":["$sd5vMK06VQ28CEnyUfZuJbiD-HXSsQXAS2-6Mm906qk"],"prev_state":[],"room_id":"!2:test","sender":"@2:test","signatures":{"test":{"ed25519:test":"oXQalkq0zQ28+KFueHLTD+hXu2oq4/MgN9w2jThn79IICDl+RDp0svYzqaYRahwbBDpTjPvWXjjiN6oJ4Z53Bw"}},"state_key":"@2:test","type":"m.room.member"}` ))
616+ jr2Ev := mustParseEvent (t , []byte (`{"auth_events":["$0B4FVZWbziXiuaBZyVerHDfBs40toK4FhoT1DNLs_tg","$B6yTeN_9fWhp5duir471Ac-OSC9BlsHnlRcbVpfmOH0","$pha7iGLaAXqkf_GAwBhPtdyjM0DF4qxiAbbc-zGJbRc"],"content":{"join_rule":"invite"},"depth":11,"hashes":{"sha256":"HtEx3O2ORo/V5Q3FHQVuPi8AvXts5tcMV5BbmsHcm+E"},"origin":"test","origin_server_ts":1697134517410,"prev_events":["$7w83ropQafHxxgMcJFWgynFXN_f1L-DgVHUPYC8KYVY"],"prev_state":[],"room_id":"!2:test","sender":"@1:test","signatures":{"test":{"ed25519:test":"5euVd5N/01mjrYQoNLlSnQWqonb2DUPSwQ4ZQz0A34fQzV3z+QjsBaIByYh2ZwkhFHnmJUvC8rUH8+JSv28NAA"}},"state_key":"","type":"m.room.join_rules"}` ))
617+
618+ // conflicted/unconflicted as calculated by Dendrite
619+ conflicted := []PDU {bobJoinEv , bobNameEv }
620+ unconflicted := []PDU {createEv , aliceJoinEv , plEv , jrEv , hisVisEv , charlieJoinEv , jr2Ev }
621+ authEvents := append (unconflicted , conflicted ... )
622+
623+ // The events we expect after state resolution
624+ expectedEvents := map [string ]PDU {
625+ "$0B4FVZWbziXiuaBZyVerHDfBs40toK4FhoT1DNLs_tg" : createEv ,
626+ "$pha7iGLaAXqkf_GAwBhPtdyjM0DF4qxiAbbc-zGJbRc" : aliceJoinEv ,
627+ "$B6yTeN_9fWhp5duir471Ac-OSC9BlsHnlRcbVpfmOH0" : plEv ,
628+ "$KvMXxqhECWclFe58hgxr_s26ytJ57olFSMv2uVjbtSo" : hisVisEv ,
629+ "$9IhOwrJzpmcAKaq05_MmKq7mqBUZENVoFOYz1_GQgX4" : charlieJoinEv ,
630+ "$IaXTO8US6DmRrPexxTucUaMoc7M0uwvMrOzWoFSsy5o" : jr2Ev ,
631+ }
632+
633+ // The join event of Bob is rejected, so don't use it to auth the name change event
634+ // This results in Bob not being in the room.
635+ var isRejected = func (eventID string ) bool {
636+ return true
637+ }
638+
639+ resolved := ResolveStateConflictsV2 (conflicted , unconflicted , authEvents , UserIDForSenderTest , isRejected )
575640 unexpectedEvents := make (map [string ]PDU )
576641 for _ , resolvedEv := range resolved {
577642 if _ , found := expectedEvents [resolvedEv .EventID ()]; ! found {
0 commit comments