Drop reference_sha column (#3083)

Companion PR to https://github.com/matrix-org/gomatrixserverlib/pull/383
This commit is contained in:
Till 2023-05-24 12:14:42 +02:00 committed by GitHub
parent 5d6221d191
commit 11b557097c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 299 additions and 227 deletions

5
.gitignore vendored
View File

@ -74,4 +74,7 @@ complement/
docs/_site docs/_site
media_store/ media_store/
build build
# golang workspaces
go.work*

View File

@ -22,7 +22,10 @@ import (
) )
func TestMonolithStarts(t *testing.T) { func TestMonolithStarts(t *testing.T) {
monolith := DendriteMonolith{} monolith := DendriteMonolith{
StorageDirectory: t.TempDir(),
CacheDirectory: t.TempDir(),
}
monolith.Start() monolith.Start()
monolith.PublicKey() monolith.PublicKey()
monolith.Stop() monolith.Stop()
@ -60,7 +63,10 @@ func TestMonolithSetRelayServers(t *testing.T) {
} }
for _, tc := range testCases { for _, tc := range testCases {
monolith := DendriteMonolith{} monolith := DendriteMonolith{
StorageDirectory: t.TempDir(),
CacheDirectory: t.TempDir(),
}
monolith.Start() monolith.Start()
inputRelays := tc.relays inputRelays := tc.relays

View File

@ -470,7 +470,7 @@ func createRoom(
} }
} }
if i > 0 { if i > 0 {
builder.PrevEvents = []gomatrixserverlib.EventReference{builtEvents[i-1].EventReference()} builder.PrevEvents = []string{builtEvents[i-1].EventID()}
} }
var ev gomatrixserverlib.PDU var ev gomatrixserverlib.PDU
if err = builder.AddAuthEvents(&authEvents); err != nil { if err = builder.AddAuthEvents(&authEvents); err != nil {

2
go.mod
View File

@ -22,7 +22,7 @@ require (
github.com/matrix-org/dugong v0.0.0-20210921133753-66e6b1c67e2e github.com/matrix-org/dugong v0.0.0-20210921133753-66e6b1c67e2e
github.com/matrix-org/go-sqlite3-js v0.0.0-20220419092513-28aa791a1c91 github.com/matrix-org/go-sqlite3-js v0.0.0-20220419092513-28aa791a1c91
github.com/matrix-org/gomatrix v0.0.0-20220926102614-ceba4d9f7530 github.com/matrix-org/gomatrix v0.0.0-20220926102614-ceba4d9f7530
github.com/matrix-org/gomatrixserverlib v0.0.0-20230523164045-3fddabebb511 github.com/matrix-org/gomatrixserverlib v0.0.0-20230524095531-95ba6c68efb6
github.com/matrix-org/pinecone v0.11.1-0.20230210171230-8c3b24f2649a github.com/matrix-org/pinecone v0.11.1-0.20230210171230-8c3b24f2649a
github.com/matrix-org/util v0.0.0-20221111132719-399730281e66 github.com/matrix-org/util v0.0.0-20221111132719-399730281e66
github.com/mattn/go-sqlite3 v1.14.16 github.com/mattn/go-sqlite3 v1.14.16

4
go.sum
View File

@ -323,8 +323,8 @@ github.com/matrix-org/go-sqlite3-js v0.0.0-20220419092513-28aa791a1c91 h1:s7fexw
github.com/matrix-org/go-sqlite3-js v0.0.0-20220419092513-28aa791a1c91/go.mod h1:e+cg2q7C7yE5QnAXgzo512tgFh1RbQLC0+jozuegKgo= github.com/matrix-org/go-sqlite3-js v0.0.0-20220419092513-28aa791a1c91/go.mod h1:e+cg2q7C7yE5QnAXgzo512tgFh1RbQLC0+jozuegKgo=
github.com/matrix-org/gomatrix v0.0.0-20220926102614-ceba4d9f7530 h1:kHKxCOLcHH8r4Fzarl4+Y3K5hjothkVW5z7T1dUM11U= github.com/matrix-org/gomatrix v0.0.0-20220926102614-ceba4d9f7530 h1:kHKxCOLcHH8r4Fzarl4+Y3K5hjothkVW5z7T1dUM11U=
github.com/matrix-org/gomatrix v0.0.0-20220926102614-ceba4d9f7530/go.mod h1:/gBX06Kw0exX1HrwmoBibFA98yBk/jxKpGVeyQbff+s= github.com/matrix-org/gomatrix v0.0.0-20220926102614-ceba4d9f7530/go.mod h1:/gBX06Kw0exX1HrwmoBibFA98yBk/jxKpGVeyQbff+s=
github.com/matrix-org/gomatrixserverlib v0.0.0-20230523164045-3fddabebb511 h1:om6z/WEVZMxZfgtiyfp5r5ubAObGMyRrnlVD07gIRY4= github.com/matrix-org/gomatrixserverlib v0.0.0-20230524095531-95ba6c68efb6 h1:FQpdh/KGCCQJytz4GAdG6pbx3DJ1HNzdKFc/BCZ0hP0=
github.com/matrix-org/gomatrixserverlib v0.0.0-20230523164045-3fddabebb511/go.mod h1:H9V9N3Uqn1bBJqYJNGK1noqtgJTaCEhtTdcH/mp50uU= github.com/matrix-org/gomatrixserverlib v0.0.0-20230524095531-95ba6c68efb6/go.mod h1:H9V9N3Uqn1bBJqYJNGK1noqtgJTaCEhtTdcH/mp50uU=
github.com/matrix-org/pinecone v0.11.1-0.20230210171230-8c3b24f2649a h1:awrPDf9LEFySxTLKYBMCiObelNx/cBuv/wzllvCCH3A= github.com/matrix-org/pinecone v0.11.1-0.20230210171230-8c3b24f2649a h1:awrPDf9LEFySxTLKYBMCiObelNx/cBuv/wzllvCCH3A=
github.com/matrix-org/pinecone v0.11.1-0.20230210171230-8c3b24f2649a/go.mod h1:HchJX9oKMXaT2xYFs0Ha/6Zs06mxLU8k6F1ODnrGkeQ= github.com/matrix-org/pinecone v0.11.1-0.20230210171230-8c3b24f2649a/go.mod h1:HchJX9oKMXaT2xYFs0Ha/6Zs06mxLU8k6F1ODnrGkeQ=
github.com/matrix-org/util v0.0.0-20221111132719-399730281e66 h1:6z4KxomXSIGWqhHcfzExgkH3Z3UkIXry4ibJS4Aqz2Y= github.com/matrix-org/util v0.0.0-20221111132719-399730281e66 h1:6z4KxomXSIGWqhHcfzExgkH3Z3UkIXry4ibJS4Aqz2Y=

View File

@ -129,18 +129,12 @@ func addPrevEventsToEvent(
return ErrRoomNoExists{} return ErrRoomNoExists{}
} }
verImpl, err := gomatrixserverlib.GetRoomVersion(queryRes.RoomVersion)
if err != nil {
return fmt.Errorf("GetRoomVersion: %w", err)
}
eventFormat := verImpl.EventFormat()
builder.Depth = queryRes.Depth builder.Depth = queryRes.Depth
authEvents := gomatrixserverlib.NewAuthEvents(nil) authEvents := gomatrixserverlib.NewAuthEvents(nil)
for i := range queryRes.StateEvents { for i := range queryRes.StateEvents {
err = authEvents.AddEvent(queryRes.StateEvents[i].PDU) err := authEvents.AddEvent(queryRes.StateEvents[i].PDU)
if err != nil { if err != nil {
return fmt.Errorf("authEvents.AddEvent: %w", err) return fmt.Errorf("authEvents.AddEvent: %w", err)
} }
@ -151,22 +145,7 @@ func addPrevEventsToEvent(
return fmt.Errorf("eventsNeeded.AuthEventReferences: %w", err) return fmt.Errorf("eventsNeeded.AuthEventReferences: %w", err)
} }
truncAuth, truncPrev := truncateAuthAndPrevEvents(refs, queryRes.LatestEvents) builder.AuthEvents, builder.PrevEvents = truncateAuthAndPrevEvents(refs, queryRes.LatestEvents)
switch eventFormat {
case gomatrixserverlib.EventFormatV1:
builder.AuthEvents = truncAuth
builder.PrevEvents = truncPrev
case gomatrixserverlib.EventFormatV2:
v2AuthRefs, v2PrevRefs := []string{}, []string{}
for _, ref := range truncAuth {
v2AuthRefs = append(v2AuthRefs, ref.EventID)
}
for _, ref := range truncPrev {
v2PrevRefs = append(v2PrevRefs, ref.EventID)
}
builder.AuthEvents = v2AuthRefs
builder.PrevEvents = v2PrevRefs
}
return nil return nil
} }
@ -176,8 +155,8 @@ func addPrevEventsToEvent(
// NOTSPEC: The limits here feel a bit arbitrary but they are currently // NOTSPEC: The limits here feel a bit arbitrary but they are currently
// here because of https://github.com/matrix-org/matrix-doc/issues/2307 // here because of https://github.com/matrix-org/matrix-doc/issues/2307
// and because Synapse will just drop events that don't comply. // and because Synapse will just drop events that don't comply.
func truncateAuthAndPrevEvents(auth, prev []gomatrixserverlib.EventReference) ( func truncateAuthAndPrevEvents(auth, prev []string) (
truncAuth, truncPrev []gomatrixserverlib.EventReference, truncAuth, truncPrev []string,
) { ) {
truncAuth, truncPrev = auth, prev truncAuth, truncPrev = auth, prev
if len(truncAuth) > 10 { if len(truncAuth) > 10 {

View File

@ -49,7 +49,7 @@ type QueryLatestEventsAndStateResponse struct {
RoomVersion gomatrixserverlib.RoomVersion `json:"room_version"` RoomVersion gomatrixserverlib.RoomVersion `json:"room_version"`
// The latest events in the room. // The latest events in the room.
// These are used to set the prev_events when sending an event. // These are used to set the prev_events when sending an event.
LatestEvents []gomatrixserverlib.EventReference `json:"latest_events"` LatestEvents []string `json:"latest_events"`
// The state events requested. // The state events requested.
// This list will be in an arbitrary order. // This list will be in an arbitrary order.
// These are used to set the auth_events when sending an event. // These are used to set the auth_events when sending an event.

View File

@ -883,9 +883,7 @@ func (r *Inputer) kickGuests(ctx context.Context, event gomatrixserverlib.PDU, r
Origin: senderDomain, Origin: senderDomain,
SendAsServer: string(senderDomain), SendAsServer: string(senderDomain),
}) })
prevEvents = []gomatrixserverlib.EventReference{ prevEvents = []string{event.EventID()}
event.EventReference(),
}
} }
inputReq := &api.InputRoomEventsRequest{ inputReq := &api.InputRoomEventsRequest{

View File

@ -154,8 +154,8 @@ func (u *latestEventsUpdater) doUpdateLatestEvents() error {
extremitiesChanged, err := u.calculateLatest( extremitiesChanged, err := u.calculateLatest(
u.oldLatest, u.event, u.oldLatest, u.event,
types.StateAtEventAndReference{ types.StateAtEventAndReference{
EventReference: u.event.EventReference(), EventID: u.event.EventID(),
StateAtEvent: u.stateAtEvent, StateAtEvent: u.stateAtEvent,
}, },
) )
if err != nil { if err != nil {
@ -349,7 +349,7 @@ func (u *latestEventsUpdater) calculateLatest(
// If the "new" event is already referenced by an existing event // If the "new" event is already referenced by an existing event
// then do nothing - it's not a candidate to be a new extremity if // then do nothing - it's not a candidate to be a new extremity if
// it has been referenced. // it has been referenced.
if referenced, err := u.updater.IsReferenced(newEvent.EventReference()); err != nil { if referenced, err := u.updater.IsReferenced(newEvent.EventID()); err != nil {
return false, fmt.Errorf("u.updater.IsReferenced(new): %w", err) return false, fmt.Errorf("u.updater.IsReferenced(new): %w", err)
} else if referenced { } else if referenced {
u.latest = oldLatest u.latest = oldLatest
@ -360,7 +360,7 @@ func (u *latestEventsUpdater) calculateLatest(
// have entries in the previous events table. If they do then we // have entries in the previous events table. If they do then we
// will no longer include them as forward extremities. // will no longer include them as forward extremities.
for k, l := range existingRefs { for k, l := range existingRefs {
referenced, err := u.updater.IsReferenced(l.EventReference) referenced, err := u.updater.IsReferenced(l.EventID)
if err != nil { if err != nil {
return false, fmt.Errorf("u.updater.IsReferenced: %w", err) return false, fmt.Errorf("u.updater.IsReferenced: %w", err)
} else if referenced { } else if referenced {

View File

@ -520,9 +520,9 @@ func (t *missingStateReq) getMissingEvents(ctx context.Context, e gomatrixserver
return nil, false, false, fmt.Errorf("t.DB.LatestEventIDs: %w", err) return nil, false, false, fmt.Errorf("t.DB.LatestEventIDs: %w", err)
} }
latestEvents := make([]string, len(latest)) latestEvents := make([]string, len(latest))
for i, ev := range latest { for i := range latest {
latestEvents[i] = ev.EventID latestEvents[i] = latest[i]
t.hadEvent(ev.EventID) t.hadEvent(latest[i])
} }
var missingResp *fclient.RespMissingEvents var missingResp *fclient.RespMissingEvents

View File

@ -131,9 +131,7 @@ func (r *Admin) PerformAdminEvacuateRoom(
SendAsServer: string(senderDomain), SendAsServer: string(senderDomain),
}) })
affected = append(affected, stateKey) affected = append(affected, stateKey)
prevEvents = []gomatrixserverlib.EventReference{ prevEvents = []string{event.EventID()}
event.EventReference(),
}
} }
inputReq := &api.InputRoomEventsRequest{ inputReq := &api.InputRoomEventsRequest{
@ -253,9 +251,9 @@ func (r *Admin) PerformAdminDownloadState(
for _, fwdExtremity := range fwdExtremities { for _, fwdExtremity := range fwdExtremities {
var state gomatrixserverlib.StateResponse var state gomatrixserverlib.StateResponse
state, err = r.Inputer.FSAPI.LookupState(ctx, r.Inputer.ServerName, serverName, roomID, fwdExtremity.EventID, roomInfo.RoomVersion) state, err = r.Inputer.FSAPI.LookupState(ctx, r.Inputer.ServerName, serverName, roomID, fwdExtremity, roomInfo.RoomVersion)
if err != nil { if err != nil {
return fmt.Errorf("r.Inputer.FSAPI.LookupState (%q): %s", fwdExtremity.EventID, err) return fmt.Errorf("r.Inputer.FSAPI.LookupState (%q): %s", fwdExtremity, err)
} }
for _, authEvent := range state.GetAuthEvents().UntrustedEvents(roomInfo.RoomVersion) { for _, authEvent := range state.GetAuthEvents().UntrustedEvents(roomInfo.RoomVersion) {
if err = gomatrixserverlib.VerifyEventSignatures(ctx, authEvent, r.Inputer.KeyRing); err != nil { if err = gomatrixserverlib.VerifyEventSignatures(ctx, authEvent, r.Inputer.KeyRing); err != nil {

View File

@ -64,7 +64,7 @@ func (r *InboundPeeker) PerformInboundPeek(
if err != nil { if err != nil {
return err return err
} }
latestEvents, err := r.DB.EventsFromIDs(ctx, info, []string{latestEventRefs[0].EventID}) latestEvents, err := r.DB.EventsFromIDs(ctx, info, []string{latestEventRefs[0]})
if err != nil { if err != nil {
return err return err
} }

View File

@ -471,7 +471,7 @@ func (r *Upgrader) sendInitialEvents(ctx context.Context, evTime time.Time, user
return fmt.Errorf("failed to set content of new %q event: %w", proto.Type, err) return fmt.Errorf("failed to set content of new %q event: %w", proto.Type, err)
} }
if i > 0 { if i > 0 {
proto.PrevEvents = []gomatrixserverlib.EventReference{builtEvents[i-1].EventReference()} proto.PrevEvents = []string{builtEvents[i-1].EventID()}
} }
var verImpl gomatrixserverlib.IRoomVersion var verImpl gomatrixserverlib.IRoomVersion

View File

@ -43,13 +43,10 @@ func createEventDB() *getEventDB {
// Adds a fake event to the storage with given auth events. // Adds a fake event to the storage with given auth events.
func (db *getEventDB) addFakeEvent(eventID string, authIDs []string) error { func (db *getEventDB) addFakeEvent(eventID string, authIDs []string) error {
authEvents := []gomatrixserverlib.EventReference{} authEvents := make([]any, 0, len(authIDs))
for _, authID := range authIDs { for _, authID := range authIDs {
authEvents = append(authEvents, gomatrixserverlib.EventReference{ authEvents = append(authEvents, []any{authID, struct{}{}})
EventID: authID,
})
} }
builder := map[string]interface{}{ builder := map[string]interface{}{
"event_id": eventID, "event_id": eventID,
"auth_events": authEvents, "auth_events": authEvents,

View File

@ -102,7 +102,7 @@ type Database interface {
// Look up event references for the latest events in the room and the current state snapshot. // Look up event references for the latest events in the room and the current state snapshot.
// Returns the latest events, the current state and the maximum depth of the latest events plus 1. // Returns the latest events, the current state and the maximum depth of the latest events plus 1.
// Returns an error if there was a problem talking to the database. // Returns an error if there was a problem talking to the database.
LatestEventIDs(ctx context.Context, roomNID types.RoomNID) ([]gomatrixserverlib.EventReference, types.StateSnapshotNID, int64, error) LatestEventIDs(ctx context.Context, roomNID types.RoomNID) ([]string, types.StateSnapshotNID, int64, error)
// Look up the active invites targeting a user in a room and return the // Look up the active invites targeting a user in a room and return the
// numeric state key IDs for the user IDs who sent them along with the event IDs for the invites. // numeric state key IDs for the user IDs who sent them along with the event IDs for the invites.
// Returns an error if there was a problem talking to the database. // Returns an error if there was a problem talking to the database.
@ -206,7 +206,7 @@ type RoomDatabase interface {
BulkSelectSnapshotsFromEventIDs(ctx context.Context, eventIDs []string) (map[types.StateSnapshotNID][]string, error) BulkSelectSnapshotsFromEventIDs(ctx context.Context, eventIDs []string) (map[types.StateSnapshotNID][]string, error)
StateEntriesForTuples(ctx context.Context, stateBlockNIDs []types.StateBlockNID, stateKeyTuples []types.StateKeyTuple) ([]types.StateEntryList, error) StateEntriesForTuples(ctx context.Context, stateBlockNIDs []types.StateBlockNID, stateKeyTuples []types.StateKeyTuple) ([]types.StateEntryList, error)
AddState(ctx context.Context, roomNID types.RoomNID, stateBlockNIDs []types.StateBlockNID, state []types.StateEntry) (types.StateSnapshotNID, error) AddState(ctx context.Context, roomNID types.RoomNID, stateBlockNIDs []types.StateBlockNID, state []types.StateEntry) (types.StateSnapshotNID, error)
LatestEventIDs(ctx context.Context, roomNID types.RoomNID) ([]gomatrixserverlib.EventReference, types.StateSnapshotNID, int64, error) LatestEventIDs(ctx context.Context, roomNID types.RoomNID) ([]string, types.StateSnapshotNID, int64, error)
GetOrCreateRoomInfo(ctx context.Context, event gomatrixserverlib.PDU) (*types.RoomInfo, error) GetOrCreateRoomInfo(ctx context.Context, event gomatrixserverlib.PDU) (*types.RoomInfo, error)
GetOrCreateEventTypeNID(ctx context.Context, eventType string) (eventTypeNID types.EventTypeNID, err error) GetOrCreateEventTypeNID(ctx context.Context, eventType string) (eventTypeNID types.EventTypeNID, err error)
GetOrCreateEventStateKeyNID(ctx context.Context, eventStateKey *string) (types.EventStateKeyNID, error) GetOrCreateEventStateKeyNID(ctx context.Context, eventStateKey *string) (types.EventStateKeyNID, error)

View File

@ -0,0 +1,54 @@
// Copyright 2023 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package deltas
import (
"context"
"database/sql"
"fmt"
)
func UpDropEventReferenceSHAEvents(ctx context.Context, tx *sql.Tx) error {
var count int
err := tx.QueryRowContext(ctx, `SELECT count(*) FROM roomserver_events GROUP BY event_id HAVING count(event_id) > 1`).
Scan(&count)
if err != nil && err != sql.ErrNoRows {
return fmt.Errorf("failed to query duplicate event ids")
}
if count > 0 {
return fmt.Errorf("unable to drop column, as there are duplicate event ids")
}
_, err = tx.ExecContext(ctx, `ALTER TABLE roomserver_events DROP COLUMN IF EXISTS reference_sha256;`)
if err != nil {
return fmt.Errorf("failed to execute upgrade: %w", err)
}
return nil
}
func UpDropEventReferenceSHAPrevEvents(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, "ALTER TABLE roomserver_previous_events DROP CONSTRAINT roomserver_previous_event_id_unique;")
if err != nil {
return fmt.Errorf("failed to execute upgrade: %w", err)
}
_, err = tx.ExecContext(ctx, `ALTER TABLE roomserver_previous_events DROP COLUMN IF EXISTS previous_reference_sha256;`)
if err != nil {
return fmt.Errorf("failed to execute upgrade: %w", err)
}
_, err = tx.ExecContext(ctx, `ALTER TABLE roomserver_previous_events ADD CONSTRAINT roomserver_previous_event_id_unique UNIQUE (previous_event_id);`)
if err != nil {
return fmt.Errorf("failed to execute upgrade: %w", err)
}
return nil
}

View File

@ -22,10 +22,9 @@ import (
"sort" "sort"
"github.com/lib/pq" "github.com/lib/pq"
"github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/dendrite/internal" "github.com/matrix-org/dendrite/internal"
"github.com/matrix-org/dendrite/internal/sqlutil" "github.com/matrix-org/dendrite/internal/sqlutil"
"github.com/matrix-org/dendrite/roomserver/storage/postgres/deltas"
"github.com/matrix-org/dendrite/roomserver/storage/tables" "github.com/matrix-org/dendrite/roomserver/storage/tables"
"github.com/matrix-org/dendrite/roomserver/types" "github.com/matrix-org/dendrite/roomserver/types"
) )
@ -62,9 +61,6 @@ CREATE TABLE IF NOT EXISTS roomserver_events (
-- Needed for state resolution. -- Needed for state resolution.
-- An event may only appear in this table once. -- An event may only appear in this table once.
event_id TEXT NOT NULL CONSTRAINT roomserver_event_id_unique UNIQUE, event_id TEXT NOT NULL CONSTRAINT roomserver_event_id_unique UNIQUE,
-- The sha256 reference hash for the event.
-- Needed for setting reference hashes when sending new events.
reference_sha256 BYTEA NOT NULL,
-- A list of numeric IDs for events that can authenticate this event. -- A list of numeric IDs for events that can authenticate this event.
auth_event_nids BIGINT[] NOT NULL, auth_event_nids BIGINT[] NOT NULL,
is_rejected BOOLEAN NOT NULL DEFAULT FALSE is_rejected BOOLEAN NOT NULL DEFAULT FALSE
@ -75,10 +71,10 @@ CREATE INDEX IF NOT EXISTS roomserver_events_memberships_idx ON roomserver_event
` `
const insertEventSQL = "" + const insertEventSQL = "" +
"INSERT INTO roomserver_events AS e (room_nid, event_type_nid, event_state_key_nid, event_id, reference_sha256, auth_event_nids, depth, is_rejected)" + "INSERT INTO roomserver_events AS e (room_nid, event_type_nid, event_state_key_nid, event_id, auth_event_nids, depth, is_rejected)" +
" VALUES ($1, $2, $3, $4, $5, $6, $7, $8)" + " VALUES ($1, $2, $3, $4, $5, $6, $7)" +
" ON CONFLICT ON CONSTRAINT roomserver_event_id_unique DO UPDATE" + " ON CONFLICT ON CONSTRAINT roomserver_event_id_unique DO UPDATE" +
" SET is_rejected = $8 WHERE e.event_id = $4 AND e.is_rejected = TRUE" + " SET is_rejected = $7 WHERE e.event_id = $4 AND e.is_rejected = TRUE" +
" RETURNING event_nid, state_snapshot_nid" " RETURNING event_nid, state_snapshot_nid"
const selectEventSQL = "" + const selectEventSQL = "" +
@ -130,12 +126,9 @@ const selectEventIDSQL = "" +
"SELECT event_id FROM roomserver_events WHERE event_nid = $1" "SELECT event_id FROM roomserver_events WHERE event_nid = $1"
const bulkSelectStateAtEventAndReferenceSQL = "" + const bulkSelectStateAtEventAndReferenceSQL = "" +
"SELECT event_type_nid, event_state_key_nid, event_nid, state_snapshot_nid, event_id, reference_sha256" + "SELECT event_type_nid, event_state_key_nid, event_nid, state_snapshot_nid, event_id" +
" FROM roomserver_events WHERE event_nid = ANY($1)" " FROM roomserver_events WHERE event_nid = ANY($1)"
const bulkSelectEventReferenceSQL = "" +
"SELECT event_id, reference_sha256 FROM roomserver_events WHERE event_nid = ANY($1)"
const bulkSelectEventIDSQL = "" + const bulkSelectEventIDSQL = "" +
"SELECT event_nid, event_id FROM roomserver_events WHERE event_nid = ANY($1)" "SELECT event_nid, event_id FROM roomserver_events WHERE event_nid = ANY($1)"
@ -167,7 +160,6 @@ type eventStatements struct {
updateEventSentToOutputStmt *sql.Stmt updateEventSentToOutputStmt *sql.Stmt
selectEventIDStmt *sql.Stmt selectEventIDStmt *sql.Stmt
bulkSelectStateAtEventAndReferenceStmt *sql.Stmt bulkSelectStateAtEventAndReferenceStmt *sql.Stmt
bulkSelectEventReferenceStmt *sql.Stmt
bulkSelectEventIDStmt *sql.Stmt bulkSelectEventIDStmt *sql.Stmt
bulkSelectEventNIDStmt *sql.Stmt bulkSelectEventNIDStmt *sql.Stmt
bulkSelectUnsentEventNIDStmt *sql.Stmt bulkSelectUnsentEventNIDStmt *sql.Stmt
@ -178,7 +170,18 @@ type eventStatements struct {
func CreateEventsTable(db *sql.DB) error { func CreateEventsTable(db *sql.DB) error {
_, err := db.Exec(eventsSchema) _, err := db.Exec(eventsSchema)
return err if err != nil {
return err
}
m := sqlutil.NewMigrator(db)
m.AddMigrations([]sqlutil.Migration{
{
Version: "roomserver: drop column reference_sha from roomserver_events",
Up: deltas.UpDropEventReferenceSHAEvents,
},
}...)
return m.Up(context.Background())
} }
func PrepareEventsTable(db *sql.DB) (tables.Events, error) { func PrepareEventsTable(db *sql.DB) (tables.Events, error) {
@ -197,7 +200,6 @@ func PrepareEventsTable(db *sql.DB) (tables.Events, error) {
{&s.selectEventSentToOutputStmt, selectEventSentToOutputSQL}, {&s.selectEventSentToOutputStmt, selectEventSentToOutputSQL},
{&s.selectEventIDStmt, selectEventIDSQL}, {&s.selectEventIDStmt, selectEventIDSQL},
{&s.bulkSelectStateAtEventAndReferenceStmt, bulkSelectStateAtEventAndReferenceSQL}, {&s.bulkSelectStateAtEventAndReferenceStmt, bulkSelectStateAtEventAndReferenceSQL},
{&s.bulkSelectEventReferenceStmt, bulkSelectEventReferenceSQL},
{&s.bulkSelectEventIDStmt, bulkSelectEventIDSQL}, {&s.bulkSelectEventIDStmt, bulkSelectEventIDSQL},
{&s.bulkSelectEventNIDStmt, bulkSelectEventNIDSQL}, {&s.bulkSelectEventNIDStmt, bulkSelectEventNIDSQL},
{&s.bulkSelectUnsentEventNIDStmt, bulkSelectUnsentEventNIDSQL}, {&s.bulkSelectUnsentEventNIDStmt, bulkSelectUnsentEventNIDSQL},
@ -214,7 +216,6 @@ func (s *eventStatements) InsertEvent(
eventTypeNID types.EventTypeNID, eventTypeNID types.EventTypeNID,
eventStateKeyNID types.EventStateKeyNID, eventStateKeyNID types.EventStateKeyNID,
eventID string, eventID string,
referenceSHA256 []byte,
authEventNIDs []types.EventNID, authEventNIDs []types.EventNID,
depth int64, depth int64,
isRejected bool, isRejected bool,
@ -224,7 +225,7 @@ func (s *eventStatements) InsertEvent(
stmt := sqlutil.TxStmt(txn, s.insertEventStmt) stmt := sqlutil.TxStmt(txn, s.insertEventStmt)
err := stmt.QueryRowContext( err := stmt.QueryRowContext(
ctx, int64(roomNID), int64(eventTypeNID), int64(eventStateKeyNID), ctx, int64(roomNID), int64(eventTypeNID), int64(eventStateKeyNID),
eventID, referenceSHA256, eventNIDsAsArray(authEventNIDs), depth, eventID, eventNIDsAsArray(authEventNIDs), depth,
isRejected, isRejected,
).Scan(&eventNID, &stateNID) ).Scan(&eventNID, &stateNID)
return types.EventNID(eventNID), types.StateSnapshotNID(stateNID), err return types.EventNID(eventNID), types.StateSnapshotNID(stateNID), err
@ -441,11 +442,10 @@ func (s *eventStatements) BulkSelectStateAtEventAndReference(
eventNID int64 eventNID int64
stateSnapshotNID int64 stateSnapshotNID int64
eventID string eventID string
eventSHA256 []byte
) )
for ; rows.Next(); i++ { for ; rows.Next(); i++ {
if err = rows.Scan( if err = rows.Scan(
&eventTypeNID, &eventStateKeyNID, &eventNID, &stateSnapshotNID, &eventID, &eventSHA256, &eventTypeNID, &eventStateKeyNID, &eventNID, &stateSnapshotNID, &eventID,
); err != nil { ); err != nil {
return nil, err return nil, err
} }
@ -455,32 +455,6 @@ func (s *eventStatements) BulkSelectStateAtEventAndReference(
result.EventNID = types.EventNID(eventNID) result.EventNID = types.EventNID(eventNID)
result.BeforeStateSnapshotNID = types.StateSnapshotNID(stateSnapshotNID) result.BeforeStateSnapshotNID = types.StateSnapshotNID(stateSnapshotNID)
result.EventID = eventID result.EventID = eventID
result.EventSHA256 = eventSHA256
}
if err = rows.Err(); err != nil {
return nil, err
}
if i != len(eventNIDs) {
return nil, fmt.Errorf("storage: event NIDs missing from the database (%d != %d)", i, len(eventNIDs))
}
return results, nil
}
func (s *eventStatements) BulkSelectEventReference(
ctx context.Context, txn *sql.Tx, eventNIDs []types.EventNID,
) ([]gomatrixserverlib.EventReference, error) {
rows, err := s.bulkSelectEventReferenceStmt.QueryContext(ctx, eventNIDsAsArray(eventNIDs))
if err != nil {
return nil, err
}
defer internal.CloseAndLogIfError(ctx, rows, "bulkSelectEventReference: rows.close() failed")
results := make([]gomatrixserverlib.EventReference, len(eventNIDs))
i := 0
for ; rows.Next(); i++ {
result := &results[i]
if err = rows.Scan(&result.EventID, &result.EventSHA256); err != nil {
return nil, err
}
} }
if err = rows.Err(); err != nil { if err = rows.Err(); err != nil {
return nil, err return nil, err

View File

@ -20,6 +20,7 @@ import (
"database/sql" "database/sql"
"github.com/matrix-org/dendrite/internal/sqlutil" "github.com/matrix-org/dendrite/internal/sqlutil"
"github.com/matrix-org/dendrite/roomserver/storage/postgres/deltas"
"github.com/matrix-org/dendrite/roomserver/storage/tables" "github.com/matrix-org/dendrite/roomserver/storage/tables"
"github.com/matrix-org/dendrite/roomserver/types" "github.com/matrix-org/dendrite/roomserver/types"
) )
@ -32,11 +33,9 @@ const previousEventSchema = `
CREATE TABLE IF NOT EXISTS roomserver_previous_events ( CREATE TABLE IF NOT EXISTS roomserver_previous_events (
-- The string event ID taken from the prev_events key of an event. -- The string event ID taken from the prev_events key of an event.
previous_event_id TEXT NOT NULL, previous_event_id TEXT NOT NULL,
-- The SHA256 reference hash taken from the prev_events key of an event.
previous_reference_sha256 BYTEA NOT NULL,
-- A list of numeric event IDs of events that reference this prev_event. -- A list of numeric event IDs of events that reference this prev_event.
event_nids BIGINT[] NOT NULL, event_nids BIGINT[] NOT NULL,
CONSTRAINT roomserver_previous_event_id_unique UNIQUE (previous_event_id, previous_reference_sha256) CONSTRAINT roomserver_previous_event_id_unique UNIQUE (previous_event_id)
); );
` `
@ -47,17 +46,17 @@ CREATE TABLE IF NOT EXISTS roomserver_previous_events (
// The lock is necessary to avoid data races when checking whether an event is already referenced by another event. // The lock is necessary to avoid data races when checking whether an event is already referenced by another event.
const insertPreviousEventSQL = "" + const insertPreviousEventSQL = "" +
"INSERT INTO roomserver_previous_events" + "INSERT INTO roomserver_previous_events" +
" (previous_event_id, previous_reference_sha256, event_nids)" + " (previous_event_id, event_nids)" +
" VALUES ($1, $2, array_append('{}'::bigint[], $3))" + " VALUES ($1, array_append('{}'::bigint[], $2))" +
" ON CONFLICT ON CONSTRAINT roomserver_previous_event_id_unique" + " ON CONFLICT ON CONSTRAINT roomserver_previous_event_id_unique" +
" DO UPDATE SET event_nids = array_append(roomserver_previous_events.event_nids, $3)" + " DO UPDATE SET event_nids = array_append(roomserver_previous_events.event_nids, $2)" +
" WHERE $3 != ALL(roomserver_previous_events.event_nids)" " WHERE $2 != ALL(roomserver_previous_events.event_nids)"
// Check if the event is referenced by another event in the table. // Check if the event is referenced by another event in the table.
// This should only be done while holding a "FOR UPDATE" lock on the row in the rooms table for this room. // This should only be done while holding a "FOR UPDATE" lock on the row in the rooms table for this room.
const selectPreviousEventExistsSQL = "" + const selectPreviousEventExistsSQL = "" +
"SELECT 1 FROM roomserver_previous_events" + "SELECT 1 FROM roomserver_previous_events" +
" WHERE previous_event_id = $1 AND previous_reference_sha256 = $2" " WHERE previous_event_id = $1"
type previousEventStatements struct { type previousEventStatements struct {
insertPreviousEventStmt *sql.Stmt insertPreviousEventStmt *sql.Stmt
@ -66,7 +65,18 @@ type previousEventStatements struct {
func CreatePrevEventsTable(db *sql.DB) error { func CreatePrevEventsTable(db *sql.DB) error {
_, err := db.Exec(previousEventSchema) _, err := db.Exec(previousEventSchema)
return err if err != nil {
return err
}
m := sqlutil.NewMigrator(db)
m.AddMigrations([]sqlutil.Migration{
{
Version: "roomserver: drop column reference_sha from roomserver_prev_events",
Up: deltas.UpDropEventReferenceSHAPrevEvents,
},
}...)
return m.Up(context.Background())
} }
func PreparePrevEventsTable(db *sql.DB) (tables.PreviousEvents, error) { func PreparePrevEventsTable(db *sql.DB) (tables.PreviousEvents, error) {
@ -82,12 +92,11 @@ func (s *previousEventStatements) InsertPreviousEvent(
ctx context.Context, ctx context.Context,
txn *sql.Tx, txn *sql.Tx,
previousEventID string, previousEventID string,
previousEventReferenceSHA256 []byte,
eventNID types.EventNID, eventNID types.EventNID,
) error { ) error {
stmt := sqlutil.TxStmt(txn, s.insertPreviousEventStmt) stmt := sqlutil.TxStmt(txn, s.insertPreviousEventStmt)
_, err := stmt.ExecContext( _, err := stmt.ExecContext(
ctx, previousEventID, previousEventReferenceSHA256, int64(eventNID), ctx, previousEventID, int64(eventNID),
) )
return err return err
} }
@ -95,9 +104,9 @@ func (s *previousEventStatements) InsertPreviousEvent(
// Check if the event reference exists // Check if the event reference exists
// Returns sql.ErrNoRows if the event reference doesn't exist. // Returns sql.ErrNoRows if the event reference doesn't exist.
func (s *previousEventStatements) SelectPreviousEventExists( func (s *previousEventStatements) SelectPreviousEventExists(
ctx context.Context, txn *sql.Tx, eventID string, eventReferenceSHA256 []byte, ctx context.Context, txn *sql.Tx, eventID string,
) error { ) error {
var ok int64 var ok int64
stmt := sqlutil.TxStmt(txn, s.selectPreviousEventExistsStmt) stmt := sqlutil.TxStmt(txn, s.selectPreviousEventExistsStmt)
return stmt.QueryRowContext(ctx, eventID, eventReferenceSHA256).Scan(&ok) return stmt.QueryRowContext(ctx, eventID).Scan(&ok)
} }

View File

@ -104,18 +104,6 @@ func (u *RoomUpdater) CurrentStateSnapshotNID() types.StateSnapshotNID {
return u.currentStateSnapshotNID return u.currentStateSnapshotNID
} }
// StorePreviousEvents implements types.RoomRecentEventsUpdater - This must be called from a Writer
func (u *RoomUpdater) StorePreviousEvents(eventNID types.EventNID, previousEventReferences []gomatrixserverlib.EventReference) error {
return u.d.Writer.Do(u.d.DB, u.txn, func(txn *sql.Tx) error {
for _, ref := range previousEventReferences {
if err := u.d.PrevEventsTable.InsertPreviousEvent(u.ctx, txn, ref.EventID, ref.EventSHA256, eventNID); err != nil {
return fmt.Errorf("u.d.PrevEventsTable.InsertPreviousEvent: %w", err)
}
}
return nil
})
}
func (u *RoomUpdater) Events(ctx context.Context, _ gomatrixserverlib.RoomVersion, eventNIDs []types.EventNID) ([]types.Event, error) { func (u *RoomUpdater) Events(ctx context.Context, _ gomatrixserverlib.RoomVersion, eventNIDs []types.EventNID) ([]types.Event, error) {
if u.roomInfo == nil { if u.roomInfo == nil {
return nil, types.ErrorInvalidRoomInfo return nil, types.ErrorInvalidRoomInfo
@ -203,8 +191,8 @@ func (u *RoomUpdater) EventsFromIDs(ctx context.Context, roomInfo *types.RoomInf
} }
// IsReferenced implements types.RoomRecentEventsUpdater // IsReferenced implements types.RoomRecentEventsUpdater
func (u *RoomUpdater) IsReferenced(eventReference gomatrixserverlib.EventReference) (bool, error) { func (u *RoomUpdater) IsReferenced(eventID string) (bool, error) {
err := u.d.PrevEventsTable.SelectPreviousEventExists(u.ctx, u.txn, eventReference.EventID, eventReference.EventSHA256) err := u.d.PrevEventsTable.SelectPreviousEventExists(u.ctx, u.txn, eventID)
if err == nil { if err == nil {
return true, nil return true, nil
} }

View File

@ -398,15 +398,13 @@ func (d *EventDatabase) eventsFromIDs(ctx context.Context, txn *sql.Tx, roomInfo
return d.events(ctx, txn, roomInfo.RoomVersion, nids) return d.events(ctx, txn, roomInfo.RoomVersion, nids)
} }
func (d *Database) LatestEventIDs( func (d *Database) LatestEventIDs(ctx context.Context, roomNID types.RoomNID) (references []string, currentStateSnapshotNID types.StateSnapshotNID, depth int64, err error) {
ctx context.Context, roomNID types.RoomNID,
) (references []gomatrixserverlib.EventReference, currentStateSnapshotNID types.StateSnapshotNID, depth int64, err error) {
var eventNIDs []types.EventNID var eventNIDs []types.EventNID
eventNIDs, currentStateSnapshotNID, err = d.RoomsTable.SelectLatestEventNIDs(ctx, nil, roomNID) eventNIDs, currentStateSnapshotNID, err = d.RoomsTable.SelectLatestEventNIDs(ctx, nil, roomNID)
if err != nil { if err != nil {
return return
} }
references, err = d.EventsTable.BulkSelectEventReference(ctx, nil, eventNIDs) eventNIDMap, err := d.EventsTable.BulkSelectEventID(ctx, nil, eventNIDs)
if err != nil { if err != nil {
return return
} }
@ -414,6 +412,9 @@ func (d *Database) LatestEventIDs(
if err != nil { if err != nil {
return return
} }
for _, eventID := range eventNIDMap {
references = append(references, eventID)
}
return return
} }
@ -742,7 +743,6 @@ func (d *EventDatabase) StoreEvent(
eventTypeNID, eventTypeNID,
eventStateKeyNID, eventStateKeyNID,
event.EventID(), event.EventID(),
event.EventReference().EventSHA256,
authEventNIDs, authEventNIDs,
event.Depth(), event.Depth(),
isRejected, isRejected,
@ -762,7 +762,7 @@ func (d *EventDatabase) StoreEvent(
return fmt.Errorf("d.EventJSONTable.InsertEventJSON: %w", err) return fmt.Errorf("d.EventJSONTable.InsertEventJSON: %w", err)
} }
if prevEvents := event.PrevEvents(); len(prevEvents) > 0 { if prevEvents := event.PrevEventIDs(); len(prevEvents) > 0 {
// Create an updater - NB: on sqlite this WILL create a txn as we are directly calling the shared DB form of // Create an updater - NB: on sqlite this WILL create a txn as we are directly calling the shared DB form of
// GetLatestEventsForUpdate - not via the SQLiteDatabase form which has `nil` txns. This // GetLatestEventsForUpdate - not via the SQLiteDatabase form which has `nil` txns. This
// function only does SELECTs though so the created txn (at this point) is just a read txn like // function only does SELECTs though so the created txn (at this point) is just a read txn like
@ -770,8 +770,8 @@ func (d *EventDatabase) StoreEvent(
// to do writes however then this will need to go inside `Writer.Do`. // to do writes however then this will need to go inside `Writer.Do`.
// The following is a copy of RoomUpdater.StorePreviousEvents // The following is a copy of RoomUpdater.StorePreviousEvents
for _, ref := range prevEvents { for _, eventID := range prevEvents {
if err = d.PrevEventsTable.InsertPreviousEvent(ctx, txn, ref.EventID, ref.EventSHA256, eventNID); err != nil { if err = d.PrevEventsTable.InsertPreviousEvent(ctx, txn, eventID, eventNID); err != nil {
return fmt.Errorf("u.d.PrevEventsTable.InsertPreviousEvent: %w", err) return fmt.Errorf("u.d.PrevEventsTable.InsertPreviousEvent: %w", err)
} }
} }

View File

@ -0,0 +1,72 @@
// Copyright 2023 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package deltas
import (
"context"
"database/sql"
"fmt"
)
func UpDropEventReferenceSHA(ctx context.Context, tx *sql.Tx) error {
var count int
err := tx.QueryRowContext(ctx, `SELECT count(*) FROM roomserver_events GROUP BY event_id HAVING count(event_id) > 1`).
Scan(&count)
if err != nil && err != sql.ErrNoRows {
return fmt.Errorf("failed to query duplicate event ids")
}
if count > 0 {
return fmt.Errorf("unable to drop column, as there are duplicate event ids")
}
_, err = tx.ExecContext(ctx, `ALTER TABLE roomserver_events DROP COLUMN reference_sha256;`)
if err != nil {
return fmt.Errorf("failed to execute upgrade: %w", err)
}
return nil
}
func UpDropEventReferenceSHAPrevEvents(ctx context.Context, tx *sql.Tx) error {
// rename the table
if _, err := tx.ExecContext(ctx, `ALTER TABLE roomserver_previous_events RENAME TO _roomserver_previous_events;`); err != nil {
return fmt.Errorf("tx.ExecContext: %w", err)
}
// create new table
if _, err := tx.ExecContext(ctx, `CREATE TABLE IF NOT EXISTS roomserver_previous_events (
previous_event_id TEXT NOT NULL,
event_nids TEXT NOT NULL,
UNIQUE (previous_event_id)
);`); err != nil {
return fmt.Errorf("tx.ExecContext: %w", err)
}
// move data
if _, err := tx.ExecContext(ctx, `
INSERT
INTO roomserver_previous_events (
previous_event_id, event_nids
) SELECT
previous_event_id, event_nids
FROM _roomserver_previous_events
;`); err != nil {
return fmt.Errorf("tx.ExecContext: %w", err)
}
// drop old table
_, err := tx.ExecContext(ctx, `DROP TABLE _roomserver_previous_events;`)
if err != nil {
return fmt.Errorf("failed to execute upgrade: %w", err)
}
return nil
}

View File

@ -19,14 +19,14 @@ import (
"context" "context"
"database/sql" "database/sql"
"encoding/json" "encoding/json"
"errors"
"fmt" "fmt"
"sort" "sort"
"strings" "strings"
"github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/dendrite/internal" "github.com/matrix-org/dendrite/internal"
"github.com/matrix-org/dendrite/internal/sqlutil" "github.com/matrix-org/dendrite/internal/sqlutil"
"github.com/matrix-org/dendrite/roomserver/storage/sqlite3/deltas"
"github.com/matrix-org/dendrite/roomserver/storage/tables" "github.com/matrix-org/dendrite/roomserver/storage/tables"
"github.com/matrix-org/dendrite/roomserver/types" "github.com/matrix-org/dendrite/roomserver/types"
) )
@ -41,17 +41,16 @@ const eventsSchema = `
state_snapshot_nid INTEGER NOT NULL DEFAULT 0, state_snapshot_nid INTEGER NOT NULL DEFAULT 0,
depth INTEGER NOT NULL, depth INTEGER NOT NULL,
event_id TEXT NOT NULL UNIQUE, event_id TEXT NOT NULL UNIQUE,
reference_sha256 BLOB NOT NULL,
auth_event_nids TEXT NOT NULL DEFAULT '[]', auth_event_nids TEXT NOT NULL DEFAULT '[]',
is_rejected BOOLEAN NOT NULL DEFAULT FALSE is_rejected BOOLEAN NOT NULL DEFAULT FALSE
); );
` `
const insertEventSQL = ` const insertEventSQL = `
INSERT INTO roomserver_events (room_nid, event_type_nid, event_state_key_nid, event_id, reference_sha256, auth_event_nids, depth, is_rejected) INSERT INTO roomserver_events (room_nid, event_type_nid, event_state_key_nid, event_id, auth_event_nids, depth, is_rejected)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8) VALUES ($1, $2, $3, $4, $5, $6, $7)
ON CONFLICT DO UPDATE ON CONFLICT DO UPDATE
SET is_rejected = $8 WHERE is_rejected = 1 SET is_rejected = $7 WHERE is_rejected = 1
RETURNING event_nid, state_snapshot_nid; RETURNING event_nid, state_snapshot_nid;
` `
@ -100,12 +99,9 @@ const selectEventIDSQL = "" +
"SELECT event_id FROM roomserver_events WHERE event_nid = $1" "SELECT event_id FROM roomserver_events WHERE event_nid = $1"
const bulkSelectStateAtEventAndReferenceSQL = "" + const bulkSelectStateAtEventAndReferenceSQL = "" +
"SELECT event_type_nid, event_state_key_nid, event_nid, state_snapshot_nid, event_id, reference_sha256" + "SELECT event_type_nid, event_state_key_nid, event_nid, state_snapshot_nid, event_id" +
" FROM roomserver_events WHERE event_nid IN ($1)" " FROM roomserver_events WHERE event_nid IN ($1)"
const bulkSelectEventReferenceSQL = "" +
"SELECT event_id, reference_sha256 FROM roomserver_events WHERE event_nid IN ($1)"
const bulkSelectEventIDSQL = "" + const bulkSelectEventIDSQL = "" +
"SELECT event_nid, event_id FROM roomserver_events WHERE event_nid IN ($1)" "SELECT event_nid, event_id FROM roomserver_events WHERE event_nid IN ($1)"
@ -137,7 +133,6 @@ type eventStatements struct {
updateEventSentToOutputStmt *sql.Stmt updateEventSentToOutputStmt *sql.Stmt
selectEventIDStmt *sql.Stmt selectEventIDStmt *sql.Stmt
bulkSelectStateAtEventAndReferenceStmt *sql.Stmt bulkSelectStateAtEventAndReferenceStmt *sql.Stmt
bulkSelectEventReferenceStmt *sql.Stmt
bulkSelectEventIDStmt *sql.Stmt bulkSelectEventIDStmt *sql.Stmt
selectEventRejectedStmt *sql.Stmt selectEventRejectedStmt *sql.Stmt
//bulkSelectEventNIDStmt *sql.Stmt //bulkSelectEventNIDStmt *sql.Stmt
@ -147,7 +142,32 @@ type eventStatements struct {
func CreateEventsTable(db *sql.DB) error { func CreateEventsTable(db *sql.DB) error {
_, err := db.Exec(eventsSchema) _, err := db.Exec(eventsSchema)
return err if err != nil {
return err
}
// check if the column exists
var cName string
migrationName := "roomserver: drop column reference_sha from roomserver_events"
err = db.QueryRowContext(context.Background(), `SELECT p.name FROM sqlite_master AS m JOIN pragma_table_info(m.name) AS p WHERE m.name = 'roomserver_events' AND p.name = 'reference_sha256'`).Scan(&cName)
if err != nil {
if errors.Is(err, sql.ErrNoRows) { // migration was already executed, as the column was removed
if err = sqlutil.InsertMigration(context.Background(), db, migrationName); err != nil {
return fmt.Errorf("unable to manually insert migration '%s': %w", migrationName, err)
}
return nil
}
return err
}
m := sqlutil.NewMigrator(db)
m.AddMigrations([]sqlutil.Migration{
{
Version: migrationName,
Up: deltas.UpDropEventReferenceSHA,
},
}...)
return m.Up(context.Background())
} }
func PrepareEventsTable(db *sql.DB) (tables.Events, error) { func PrepareEventsTable(db *sql.DB) (tables.Events, error) {
@ -167,7 +187,6 @@ func PrepareEventsTable(db *sql.DB) (tables.Events, error) {
{&s.selectEventSentToOutputStmt, selectEventSentToOutputSQL}, {&s.selectEventSentToOutputStmt, selectEventSentToOutputSQL},
{&s.selectEventIDStmt, selectEventIDSQL}, {&s.selectEventIDStmt, selectEventIDSQL},
{&s.bulkSelectStateAtEventAndReferenceStmt, bulkSelectStateAtEventAndReferenceSQL}, {&s.bulkSelectStateAtEventAndReferenceStmt, bulkSelectStateAtEventAndReferenceSQL},
{&s.bulkSelectEventReferenceStmt, bulkSelectEventReferenceSQL},
{&s.bulkSelectEventIDStmt, bulkSelectEventIDSQL}, {&s.bulkSelectEventIDStmt, bulkSelectEventIDSQL},
//{&s.bulkSelectEventNIDStmt, bulkSelectEventNIDSQL}, //{&s.bulkSelectEventNIDStmt, bulkSelectEventNIDSQL},
//{&s.bulkSelectUnsentEventNIDStmt, bulkSelectUnsentEventNIDSQL}, //{&s.bulkSelectUnsentEventNIDStmt, bulkSelectUnsentEventNIDSQL},
@ -183,7 +202,6 @@ func (s *eventStatements) InsertEvent(
eventTypeNID types.EventTypeNID, eventTypeNID types.EventTypeNID,
eventStateKeyNID types.EventStateKeyNID, eventStateKeyNID types.EventStateKeyNID,
eventID string, eventID string,
referenceSHA256 []byte,
authEventNIDs []types.EventNID, authEventNIDs []types.EventNID,
depth int64, depth int64,
isRejected bool, isRejected bool,
@ -194,7 +212,7 @@ func (s *eventStatements) InsertEvent(
insertStmt := sqlutil.TxStmt(txn, s.insertEventStmt) insertStmt := sqlutil.TxStmt(txn, s.insertEventStmt)
err := insertStmt.QueryRowContext( err := insertStmt.QueryRowContext(
ctx, int64(roomNID), int64(eventTypeNID), int64(eventStateKeyNID), ctx, int64(roomNID), int64(eventTypeNID), int64(eventStateKeyNID),
eventID, referenceSHA256, eventNIDsAsArray(authEventNIDs), depth, isRejected, eventID, eventNIDsAsArray(authEventNIDs), depth, isRejected,
).Scan(&eventNID, &stateNID) ).Scan(&eventNID, &stateNID)
return types.EventNID(eventNID), types.StateSnapshotNID(stateNID), err return types.EventNID(eventNID), types.StateSnapshotNID(stateNID), err
} }
@ -475,11 +493,10 @@ func (s *eventStatements) BulkSelectStateAtEventAndReference(
eventNID int64 eventNID int64
stateSnapshotNID int64 stateSnapshotNID int64
eventID string eventID string
eventSHA256 []byte
) )
for ; rows.Next(); i++ { for ; rows.Next(); i++ {
if err = rows.Scan( if err = rows.Scan(
&eventTypeNID, &eventStateKeyNID, &eventNID, &stateSnapshotNID, &eventID, &eventSHA256, &eventTypeNID, &eventStateKeyNID, &eventNID, &stateSnapshotNID, &eventID,
); err != nil { ); err != nil {
return nil, err return nil, err
} }
@ -489,43 +506,6 @@ func (s *eventStatements) BulkSelectStateAtEventAndReference(
result.EventNID = types.EventNID(eventNID) result.EventNID = types.EventNID(eventNID)
result.BeforeStateSnapshotNID = types.StateSnapshotNID(stateSnapshotNID) result.BeforeStateSnapshotNID = types.StateSnapshotNID(stateSnapshotNID)
result.EventID = eventID result.EventID = eventID
result.EventSHA256 = eventSHA256
}
if i != len(eventNIDs) {
return nil, fmt.Errorf("storage: event NIDs missing from the database (%d != %d)", i, len(eventNIDs))
}
return results, nil
}
func (s *eventStatements) BulkSelectEventReference(
ctx context.Context, txn *sql.Tx, eventNIDs []types.EventNID,
) ([]gomatrixserverlib.EventReference, error) {
///////////////
iEventNIDs := make([]interface{}, len(eventNIDs))
for k, v := range eventNIDs {
iEventNIDs[k] = v
}
selectOrig := strings.Replace(bulkSelectEventReferenceSQL, "($1)", sqlutil.QueryVariadic(len(iEventNIDs)), 1)
selectPrep, err := s.db.Prepare(selectOrig)
if err != nil {
return nil, err
}
defer selectPrep.Close() // nolint:errcheck
///////////////
selectStmt := sqlutil.TxStmt(txn, selectPrep)
rows, err := selectStmt.QueryContext(ctx, iEventNIDs...)
if err != nil {
return nil, err
}
defer internal.CloseAndLogIfError(ctx, rows, "bulkSelectEventReference: rows.close() failed")
results := make([]gomatrixserverlib.EventReference, len(eventNIDs))
i := 0
for ; rows.Next(); i++ {
result := &results[i]
if err = rows.Scan(&result.EventID, &result.EventSHA256); err != nil {
return nil, err
}
} }
if i != len(eventNIDs) { if i != len(eventNIDs) {
return nil, fmt.Errorf("storage: event NIDs missing from the database (%d != %d)", i, len(eventNIDs)) return nil, fmt.Errorf("storage: event NIDs missing from the database (%d != %d)", i, len(eventNIDs))

View File

@ -18,10 +18,12 @@ package sqlite3
import ( import (
"context" "context"
"database/sql" "database/sql"
"errors"
"fmt" "fmt"
"strings" "strings"
"github.com/matrix-org/dendrite/internal/sqlutil" "github.com/matrix-org/dendrite/internal/sqlutil"
"github.com/matrix-org/dendrite/roomserver/storage/sqlite3/deltas"
"github.com/matrix-org/dendrite/roomserver/storage/tables" "github.com/matrix-org/dendrite/roomserver/storage/tables"
"github.com/matrix-org/dendrite/roomserver/types" "github.com/matrix-org/dendrite/roomserver/types"
) )
@ -34,9 +36,8 @@ import (
const previousEventSchema = ` const previousEventSchema = `
CREATE TABLE IF NOT EXISTS roomserver_previous_events ( CREATE TABLE IF NOT EXISTS roomserver_previous_events (
previous_event_id TEXT NOT NULL, previous_event_id TEXT NOT NULL,
previous_reference_sha256 BLOB,
event_nids TEXT NOT NULL, event_nids TEXT NOT NULL,
UNIQUE (previous_event_id, previous_reference_sha256) UNIQUE (previous_event_id)
); );
` `
@ -47,20 +48,20 @@ const previousEventSchema = `
// The lock is necessary to avoid data races when checking whether an event is already referenced by another event. // The lock is necessary to avoid data races when checking whether an event is already referenced by another event.
const insertPreviousEventSQL = ` const insertPreviousEventSQL = `
INSERT OR REPLACE INTO roomserver_previous_events INSERT OR REPLACE INTO roomserver_previous_events
(previous_event_id, previous_reference_sha256, event_nids) (previous_event_id, event_nids)
VALUES ($1, $2, $3) VALUES ($1, $2)
` `
const selectPreviousEventNIDsSQL = ` const selectPreviousEventNIDsSQL = `
SELECT event_nids FROM roomserver_previous_events SELECT event_nids FROM roomserver_previous_events
WHERE previous_event_id = $1 AND previous_reference_sha256 = $2 WHERE previous_event_id = $1
` `
// Check if the event is referenced by another event in the table. // Check if the event is referenced by another event in the table.
// This should only be done while holding a "FOR UPDATE" lock on the row in the rooms table for this room. // This should only be done while holding a "FOR UPDATE" lock on the row in the rooms table for this room.
const selectPreviousEventExistsSQL = ` const selectPreviousEventExistsSQL = `
SELECT 1 FROM roomserver_previous_events SELECT 1 FROM roomserver_previous_events
WHERE previous_event_id = $1 AND previous_reference_sha256 = $2 WHERE previous_event_id = $1
` `
type previousEventStatements struct { type previousEventStatements struct {
@ -72,7 +73,30 @@ type previousEventStatements struct {
func CreatePrevEventsTable(db *sql.DB) error { func CreatePrevEventsTable(db *sql.DB) error {
_, err := db.Exec(previousEventSchema) _, err := db.Exec(previousEventSchema)
return err if err != nil {
return err
}
// check if the column exists
var cName string
migrationName := "roomserver: drop column reference_sha from roomserver_prev_events"
err = db.QueryRowContext(context.Background(), `SELECT p.name FROM sqlite_master AS m JOIN pragma_table_info(m.name) AS p WHERE m.name = 'roomserver_previous_events' AND p.name = 'previous_reference_sha256'`).Scan(&cName)
if err != nil {
if errors.Is(err, sql.ErrNoRows) { // migration was already executed, as the column was removed
if err = sqlutil.InsertMigration(context.Background(), db, migrationName); err != nil {
return fmt.Errorf("unable to manually insert migration '%s': %w", migrationName, err)
}
return nil
}
return err
}
m := sqlutil.NewMigrator(db)
m.AddMigrations([]sqlutil.Migration{
{
Version: migrationName,
Up: deltas.UpDropEventReferenceSHAPrevEvents,
},
}...)
return m.Up(context.Background())
} }
func PreparePrevEventsTable(db *sql.DB) (tables.PreviousEvents, error) { func PreparePrevEventsTable(db *sql.DB) (tables.PreviousEvents, error) {
@ -91,13 +115,12 @@ func (s *previousEventStatements) InsertPreviousEvent(
ctx context.Context, ctx context.Context,
txn *sql.Tx, txn *sql.Tx,
previousEventID string, previousEventID string,
previousEventReferenceSHA256 []byte,
eventNID types.EventNID, eventNID types.EventNID,
) error { ) error {
var eventNIDs string var eventNIDs string
eventNIDAsString := fmt.Sprintf("%d", eventNID) eventNIDAsString := fmt.Sprintf("%d", eventNID)
selectStmt := sqlutil.TxStmt(txn, s.selectPreviousEventExistsStmt) selectStmt := sqlutil.TxStmt(txn, s.selectPreviousEventExistsStmt)
err := selectStmt.QueryRowContext(ctx, previousEventID, previousEventReferenceSHA256).Scan(&eventNIDs) err := selectStmt.QueryRowContext(ctx, previousEventID).Scan(&eventNIDs)
if err != nil && err != sql.ErrNoRows { if err != nil && err != sql.ErrNoRows {
return fmt.Errorf("selectStmt.QueryRowContext.Scan: %w", err) return fmt.Errorf("selectStmt.QueryRowContext.Scan: %w", err)
} }
@ -115,7 +138,7 @@ func (s *previousEventStatements) InsertPreviousEvent(
} }
insertStmt := sqlutil.TxStmt(txn, s.insertPreviousEventStmt) insertStmt := sqlutil.TxStmt(txn, s.insertPreviousEventStmt)
_, err = insertStmt.ExecContext( _, err = insertStmt.ExecContext(
ctx, previousEventID, previousEventReferenceSHA256, eventNIDs, ctx, previousEventID, eventNIDs,
) )
return err return err
} }
@ -123,9 +146,9 @@ func (s *previousEventStatements) InsertPreviousEvent(
// Check if the event reference exists // Check if the event reference exists
// Returns sql.ErrNoRows if the event reference doesn't exist. // Returns sql.ErrNoRows if the event reference doesn't exist.
func (s *previousEventStatements) SelectPreviousEventExists( func (s *previousEventStatements) SelectPreviousEventExists(
ctx context.Context, txn *sql.Tx, eventID string, eventReferenceSHA256 []byte, ctx context.Context, txn *sql.Tx, eventID string,
) error { ) error {
var ok int64 var ok int64
stmt := sqlutil.TxStmt(txn, s.selectPreviousEventExistsStmt) stmt := sqlutil.TxStmt(txn, s.selectPreviousEventExistsStmt)
return stmt.QueryRowContext(ctx, eventID, eventReferenceSHA256).Scan(&ok) return stmt.QueryRowContext(ctx, eventID).Scan(&ok)
} }

View File

@ -21,14 +21,13 @@ import (
"errors" "errors"
"fmt" "fmt"
"github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/dendrite/internal/caching" "github.com/matrix-org/dendrite/internal/caching"
"github.com/matrix-org/dendrite/internal/sqlutil" "github.com/matrix-org/dendrite/internal/sqlutil"
"github.com/matrix-org/dendrite/roomserver/storage/shared" "github.com/matrix-org/dendrite/roomserver/storage/shared"
"github.com/matrix-org/dendrite/roomserver/storage/sqlite3/deltas" "github.com/matrix-org/dendrite/roomserver/storage/sqlite3/deltas"
"github.com/matrix-org/dendrite/roomserver/types" "github.com/matrix-org/dendrite/roomserver/types"
"github.com/matrix-org/dendrite/setup/config" "github.com/matrix-org/dendrite/setup/config"
"github.com/matrix-org/gomatrixserverlib"
) )
// A Database is used to store room events and stream offsets. // A Database is used to store room events and stream offsets.

View File

@ -11,7 +11,6 @@ import (
"github.com/matrix-org/dendrite/roomserver/types" "github.com/matrix-org/dendrite/roomserver/types"
"github.com/matrix-org/dendrite/setup/config" "github.com/matrix-org/dendrite/setup/config"
"github.com/matrix-org/dendrite/test" "github.com/matrix-org/dendrite/test"
"github.com/matrix-org/gomatrixserverlib"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -48,10 +47,9 @@ func Test_EventsTable(t *testing.T) {
// create some dummy data // create some dummy data
eventIDs := make([]string, 0, len(room.Events())) eventIDs := make([]string, 0, len(room.Events()))
wantStateAtEvent := make([]types.StateAtEvent, 0, len(room.Events())) wantStateAtEvent := make([]types.StateAtEvent, 0, len(room.Events()))
wantEventReferences := make([]gomatrixserverlib.EventReference, 0, len(room.Events()))
wantStateAtEventAndRefs := make([]types.StateAtEventAndReference, 0, len(room.Events())) wantStateAtEventAndRefs := make([]types.StateAtEventAndReference, 0, len(room.Events()))
for _, ev := range room.Events() { for _, ev := range room.Events() {
eventNID, snapNID, err := tab.InsertEvent(ctx, nil, 1, 1, 1, ev.EventID(), ev.EventReference().EventSHA256, nil, ev.Depth(), false) eventNID, snapNID, err := tab.InsertEvent(ctx, nil, 1, 1, 1, ev.EventID(), nil, ev.Depth(), false)
assert.NoError(t, err) assert.NoError(t, err)
gotEventNID, gotSnapNID, err := tab.SelectEvent(ctx, nil, ev.EventID()) gotEventNID, gotSnapNID, err := tab.SelectEvent(ctx, nil, ev.EventID())
assert.NoError(t, err) assert.NoError(t, err)
@ -75,7 +73,6 @@ func Test_EventsTable(t *testing.T) {
assert.True(t, sentToOutput) assert.True(t, sentToOutput)
eventIDs = append(eventIDs, ev.EventID()) eventIDs = append(eventIDs, ev.EventID())
wantEventReferences = append(wantEventReferences, ev.EventReference())
// Set the stateSnapshot to 2 for some events to verify they are returned later // Set the stateSnapshot to 2 for some events to verify they are returned later
stateSnapshot := 0 stateSnapshot := 0
@ -97,8 +94,8 @@ func Test_EventsTable(t *testing.T) {
} }
wantStateAtEvent = append(wantStateAtEvent, stateAtEvent) wantStateAtEvent = append(wantStateAtEvent, stateAtEvent)
wantStateAtEventAndRefs = append(wantStateAtEventAndRefs, types.StateAtEventAndReference{ wantStateAtEventAndRefs = append(wantStateAtEventAndRefs, types.StateAtEventAndReference{
StateAtEvent: stateAtEvent, StateAtEvent: stateAtEvent,
EventReference: ev.EventReference(), EventID: ev.EventID(),
}) })
} }
@ -140,10 +137,6 @@ func Test_EventsTable(t *testing.T) {
assert.True(t, ok) assert.True(t, ok)
} }
references, err := tab.BulkSelectEventReference(ctx, nil, nids)
assert.NoError(t, err)
assert.Equal(t, wantEventReferences, references)
stateAndRefs, err := tab.BulkSelectStateAtEventAndReference(ctx, nil, nids) stateAndRefs, err := tab.BulkSelectStateAtEventAndReference(ctx, nil, nids)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, wantStateAtEventAndRefs, stateAndRefs) assert.Equal(t, wantStateAtEventAndRefs, stateAndRefs)

View File

@ -42,7 +42,7 @@ type Events interface {
InsertEvent( InsertEvent(
ctx context.Context, txn *sql.Tx, roomNID types.RoomNID, eventTypeNID types.EventTypeNID, ctx context.Context, txn *sql.Tx, roomNID types.RoomNID, eventTypeNID types.EventTypeNID,
eventStateKeyNID types.EventStateKeyNID, eventID string, eventStateKeyNID types.EventStateKeyNID, eventID string,
referenceSHA256 []byte, authEventNIDs []types.EventNID, depth int64, isRejected bool, authEventNIDs []types.EventNID, depth int64, isRejected bool,
) (types.EventNID, types.StateSnapshotNID, error) ) (types.EventNID, types.StateSnapshotNID, error)
SelectEvent(ctx context.Context, txn *sql.Tx, eventID string) (types.EventNID, types.StateSnapshotNID, error) SelectEvent(ctx context.Context, txn *sql.Tx, eventID string) (types.EventNID, types.StateSnapshotNID, error)
BulkSelectSnapshotsFromEventIDs(ctx context.Context, txn *sql.Tx, eventIDs []string) (map[types.StateSnapshotNID][]string, error) BulkSelectSnapshotsFromEventIDs(ctx context.Context, txn *sql.Tx, eventIDs []string) (map[types.StateSnapshotNID][]string, error)
@ -59,7 +59,6 @@ type Events interface {
UpdateEventSentToOutput(ctx context.Context, txn *sql.Tx, eventNID types.EventNID) error UpdateEventSentToOutput(ctx context.Context, txn *sql.Tx, eventNID types.EventNID) error
SelectEventID(ctx context.Context, txn *sql.Tx, eventNID types.EventNID) (eventID string, err error) SelectEventID(ctx context.Context, txn *sql.Tx, eventNID types.EventNID) (eventID string, err error)
BulkSelectStateAtEventAndReference(ctx context.Context, txn *sql.Tx, eventNIDs []types.EventNID) ([]types.StateAtEventAndReference, error) BulkSelectStateAtEventAndReference(ctx context.Context, txn *sql.Tx, eventNIDs []types.EventNID) ([]types.StateAtEventAndReference, error)
BulkSelectEventReference(ctx context.Context, txn *sql.Tx, eventNIDs []types.EventNID) ([]gomatrixserverlib.EventReference, error)
// BulkSelectEventID returns a map from numeric event ID to string event ID. // BulkSelectEventID returns a map from numeric event ID to string event ID.
BulkSelectEventID(ctx context.Context, txn *sql.Tx, eventNIDs []types.EventNID) (map[types.EventNID]string, error) BulkSelectEventID(ctx context.Context, txn *sql.Tx, eventNIDs []types.EventNID) (map[types.EventNID]string, error)
// BulkSelectEventNIDs returns a map from string event ID to numeric event ID. // BulkSelectEventNIDs returns a map from string event ID to numeric event ID.
@ -113,10 +112,10 @@ type RoomAliases interface {
} }
type PreviousEvents interface { type PreviousEvents interface {
InsertPreviousEvent(ctx context.Context, txn *sql.Tx, previousEventID string, previousEventReferenceSHA256 []byte, eventNID types.EventNID) error InsertPreviousEvent(ctx context.Context, txn *sql.Tx, previousEventID string, eventNID types.EventNID) error
// Check if the event reference exists // Check if the event reference exists
// Returns sql.ErrNoRows if the event reference doesn't exist. // Returns sql.ErrNoRows if the event reference doesn't exist.
SelectPreviousEventExists(ctx context.Context, txn *sql.Tx, eventID string, eventReferenceSHA256 []byte) error SelectPreviousEventExists(ctx context.Context, txn *sql.Tx, eventID string) error
} }
type Invites interface { type Invites interface {

View File

@ -45,17 +45,17 @@ func TestPreviousEventsTable(t *testing.T) {
defer close() defer close()
for _, x := range room.Events() { for _, x := range room.Events() {
for _, prevEvent := range x.PrevEvents() { for _, eventID := range x.PrevEventIDs() {
err := tab.InsertPreviousEvent(ctx, nil, prevEvent.EventID, prevEvent.EventSHA256, 1) err := tab.InsertPreviousEvent(ctx, nil, eventID, 1)
assert.NoError(t, err) assert.NoError(t, err)
err = tab.SelectPreviousEventExists(ctx, nil, prevEvent.EventID, prevEvent.EventSHA256) err = tab.SelectPreviousEventExists(ctx, nil, eventID)
assert.NoError(t, err) assert.NoError(t, err)
} }
} }
// RandomString with a correct EventSHA256 should fail and return sql.ErrNoRows // RandomString should fail and return sql.ErrNoRows
err := tab.SelectPreviousEventExists(ctx, nil, util.RandomString(16), room.Events()[0].EventReference().EventSHA256) err := tab.SelectPreviousEventExists(ctx, nil, util.RandomString(16))
assert.Error(t, err) assert.Error(t, err)
}) })
} }

View File

@ -200,7 +200,7 @@ func (s StateAtEvent) IsStateEvent() bool {
// The StateAtEvent is used to construct the current state of the room from the latest events. // The StateAtEvent is used to construct the current state of the room from the latest events.
type StateAtEventAndReference struct { type StateAtEventAndReference struct {
StateAtEvent StateAtEvent
gomatrixserverlib.EventReference EventID string
} }
type StateAtEventAndReferences []StateAtEventAndReference type StateAtEventAndReferences []StateAtEventAndReference

View File

@ -75,7 +75,7 @@ func NewRoom(t *testing.T, creator *User, modifiers ...roomModifier) *Room {
return r return r
} }
func (r *Room) MustGetAuthEventRefsForEvent(t *testing.T, needed gomatrixserverlib.StateNeeded) []gomatrixserverlib.EventReference { func (r *Room) MustGetAuthEventRefsForEvent(t *testing.T, needed gomatrixserverlib.StateNeeded) []string {
t.Helper() t.Helper()
a, err := needed.AuthEventReferences(&r.authEvents) a, err := needed.AuthEventReferences(&r.authEvents)
if err != nil { if err != nil {
@ -176,7 +176,7 @@ func (r *Room) CreateEvent(t *testing.T, creator *User, eventType string, conten
t.Fatalf("CreateEvent[%s]: failed to SetContent: %s", eventType, err) t.Fatalf("CreateEvent[%s]: failed to SetContent: %s", eventType, err)
} }
if depth > 1 { if depth > 1 {
builder.PrevEvents = []gomatrixserverlib.EventReference{r.events[len(r.events)-1].EventReference()} builder.PrevEvents = []string{r.events[len(r.events)-1].EventID()}
} }
err = builder.AddAuthEvents(&r.authEvents) err = builder.AddAuthEvents(&r.authEvents)