mirror of
https://github.com/block/buzz.git
synced 2026-10-29 13:31:44 +00:00
142 lines
5.1 KiB
SQL
142 lines
5.1 KiB
SQL
-- Run after schema migration 0067 and after the new relay is fully rolled out
|
|
-- and all old writers are drained. Keep invite mint/claim and ban lifts paused
|
|
-- until this repair and its final validation succeed.
|
|
--
|
|
-- Each community batch commits independently, takes the same lock order as the
|
|
-- application writers, and skips a community unless it is active and has no
|
|
-- deletion timestamp. The script is idempotent; rerun it after a failure.
|
|
\set ON_ERROR_STOP on
|
|
SET lock_timeout = '5s';
|
|
SET statement_timeout = '2min';
|
|
|
|
DO $$
|
|
DECLARE
|
|
last_community UUID;
|
|
target_community UUID;
|
|
community_active BOOLEAN;
|
|
affected BIGINT;
|
|
BEGIN
|
|
LOOP
|
|
SELECT id INTO target_community
|
|
FROM communities
|
|
WHERE last_community IS NULL OR id > last_community
|
|
ORDER BY id
|
|
LIMIT 1;
|
|
EXIT WHEN NOT FOUND;
|
|
last_community := target_community;
|
|
|
|
LOOP
|
|
PERFORM pg_advisory_xact_lock_shared(
|
|
community_deletion_lock_key(target_community)
|
|
);
|
|
PERFORM pg_advisory_xact_lock(
|
|
hashtextextended('invite-admission:' || target_community::text, 0)
|
|
);
|
|
SELECT deletion_state = 'active' AND deleted_at IS NULL
|
|
INTO community_active
|
|
FROM communities
|
|
WHERE id = target_community;
|
|
|
|
IF community_active IS DISTINCT FROM TRUE THEN
|
|
COMMIT;
|
|
EXIT;
|
|
END IF;
|
|
|
|
WITH candidates AS (
|
|
SELECT invite.id
|
|
FROM relay_invites AS invite
|
|
CROSS JOIN LATERAL (
|
|
SELECT CASE
|
|
WHEN octet_length(invite.created_by) = 64
|
|
AND invite.created_by !~ '[^0-9a-f]'
|
|
THEN decode(invite.created_by, 'hex')
|
|
END AS pubkey
|
|
) AS issuer
|
|
WHERE invite.community_id = target_community
|
|
AND invite.revoked_at IS NULL
|
|
AND (
|
|
EXISTS (
|
|
SELECT 1
|
|
FROM community_bans AS restriction
|
|
WHERE restriction.community_id = invite.community_id
|
|
AND (
|
|
restriction.pubkey = issuer.pubkey
|
|
OR restriction.pubkey = (
|
|
SELECT user_row.agent_owner_pubkey
|
|
FROM users AS user_row
|
|
WHERE user_row.community_id = invite.community_id
|
|
AND user_row.pubkey = issuer.pubkey
|
|
)
|
|
)
|
|
AND (
|
|
invite.legacy_admission
|
|
OR (
|
|
restriction.banned
|
|
AND (restriction.ban_expires_at IS NULL
|
|
OR restriction.ban_expires_at > clock_timestamp())
|
|
)
|
|
)
|
|
)
|
|
OR (invite.legacy_admission AND issuer.pubkey IS NULL)
|
|
)
|
|
ORDER BY invite.id
|
|
LIMIT 500
|
|
FOR UPDATE OF invite
|
|
)
|
|
UPDATE relay_invites AS invite
|
|
SET revoked_at = clock_timestamp()
|
|
FROM candidates
|
|
WHERE invite.community_id = target_community
|
|
AND invite.id = candidates.id
|
|
AND invite.revoked_at IS NULL;
|
|
GET DIAGNOSTICS affected = ROW_COUNT;
|
|
|
|
COMMIT;
|
|
EXIT WHEN affected = 0;
|
|
END LOOP;
|
|
END LOOP;
|
|
END
|
|
$$;
|
|
|
|
-- Expected result: 0. This includes active bans for every invite and every
|
|
-- retained restriction row (including lifted and timeout-only rows) for legacy
|
|
-- issuers or their currently recorded owners in active communities.
|
|
SELECT count(*) AS unrepaired_invites
|
|
FROM relay_invites AS invite
|
|
JOIN communities AS community ON community.id = invite.community_id
|
|
CROSS JOIN LATERAL (
|
|
SELECT CASE
|
|
WHEN octet_length(invite.created_by) = 64
|
|
AND invite.created_by !~ '[^0-9a-f]'
|
|
THEN decode(invite.created_by, 'hex')
|
|
END AS pubkey
|
|
) AS issuer
|
|
WHERE community.deletion_state = 'active'
|
|
AND community.deleted_at IS NULL
|
|
AND invite.revoked_at IS NULL
|
|
AND (
|
|
EXISTS (
|
|
SELECT 1
|
|
FROM community_bans AS restriction
|
|
WHERE restriction.community_id = invite.community_id
|
|
AND (
|
|
restriction.pubkey = issuer.pubkey
|
|
OR restriction.pubkey = (
|
|
SELECT user_row.agent_owner_pubkey
|
|
FROM users AS user_row
|
|
WHERE user_row.community_id = invite.community_id
|
|
AND user_row.pubkey = issuer.pubkey
|
|
)
|
|
)
|
|
AND (
|
|
invite.legacy_admission
|
|
OR (
|
|
restriction.banned
|
|
AND (restriction.ban_expires_at IS NULL
|
|
OR restriction.ban_expires_at > clock_timestamp())
|
|
)
|
|
)
|
|
)
|
|
OR (invite.legacy_admission AND issuer.pubkey IS NULL)
|
|
);
|