Files
buzz/migrations/0007_nip_rs_retention.sql
T
cls 9dfa06ffee
Docker image / Build (linux/amd64) (push) Has been cancelled
Docker image / Build (linux/arm64) (push) Has been cancelled
Docker image / Merge release multi-arch manifest (push) Has been cancelled
Docker image / Merge debug multi-arch manifest (push) Has been cancelled
Docker image / Build public push gateway (linux/amd64) (push) Has been cancelled
Docker image / Build public push gateway (linux/arm64) (push) Has been cancelled
Docker image / Publish public push gateway image (push) Has been cancelled
Sprig image / Build (linux/amd64) (push) Has been cancelled
Sprig image / Build (linux/arm64) (push) Has been cancelled
Sprig image / Merge multi-arch manifest (push) Has been cancelled
Harbor Buzz Orchestra / Python tests and lint (push) Has been cancelled
CI / Detect Changed Paths (push) Has been cancelled
CI / Rust Lint (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Desktop Core (push) Has been cancelled
CI / Desktop Smoke E2E (1) (push) Has been cancelled
CI / Desktop Smoke E2E (2) (push) Has been cancelled
CI / Desktop Smoke E2E (3) (push) Has been cancelled
CI / Desktop Smoke E2E (4) (push) Has been cancelled
CI / Desktop (push) Has been cancelled
CI / Desktop E2E Relay (push) Has been cancelled
CI / Desktop E2E Integration (1/2) (push) Has been cancelled
CI / Desktop E2E Integration (2/2) (push) Has been cancelled
CI / Desktop E2E Integration (push) Has been cancelled
CI / Backend Integration (relay e2e) (push) Has been cancelled
CI / Relay E2E (push) Has been cancelled
CI / Web (push) Has been cancelled
CI / Mobile (push) Has been cancelled
CI / Security (push) Has been cancelled
CI / Dead Token Reference Guard (push) Has been cancelled
CI / Server Cross-Compile (aarch64-unknown-linux-musl) (push) Has been cancelled
CI / Server Cross-Compile (x86_64-unknown-linux-musl) (push) Has been cancelled
CI / Windows Rust (x86_64-pc-windows-msvc) (push) Has been cancelled
CI / Desktop Build (macOS) (push) Has been cancelled
helm chart / lint + unittest + render matrix (push) Has been cancelled
helm chart / install on kind (gated) (push) Has been cancelled
helm chart / publish chart to GHCR (push) Has been cancelled
Mesh Lifecycle / Relay-Driven Mesh Lifecycle Smoke (push) Has been cancelled
Sprig / Build (aarch64-unknown-linux-musl) (push) Has been cancelled
Sprig / Build (x86_64-unknown-linux-musl) (push) Has been cancelled
Sprig / Publish rolling release (push) Has been cancelled
Sprig / Publish tagged release (push) Has been cancelled
feat: import Chinese-localized Buzz source snapshot
Signed-off-by: cls_宁波本机 <908705107@qq.com>
2026-08-13 18:34:25 +08:00

141 lines
5.3 KiB
SQL

-- Bound NIP-RS storage while preserving NIP-33 replay ordering.
--
-- The payload table previously retained every superseded kind:30078 event as a
-- soft-deleted row. Besides keeping the encrypted blob, search_tsv tokenized it
-- and the GIN index amplified it further. A compact ordering watermark retains
-- the only historical fact replacement needs without retaining user payloads.
-- The relay may still have old instances writing during a rolling deploy. Hold a
-- table-level writer lock for this transaction so the seed is a complete
-- high-water mark: without it, an old instance could insert between the seed
-- and purge, then a later NIP-09 deletion could reopen a replay window. Reads
-- remain available; inserts, updates, and deletes wait for migration commit.
LOCK TABLE events IN SHARE ROW EXCLUSIVE MODE;
CREATE TABLE parameterized_event_watermarks (
community_id UUID NOT NULL REFERENCES communities(id),
kind INT NOT NULL,
pubkey BYTEA NOT NULL,
d_tag TEXT NOT NULL,
created_at TIMESTAMPTZ NOT NULL,
event_id BYTEA NOT NULL,
PRIMARY KEY (community_id, kind, pubkey, d_tag)
);
-- Superseded read-state events normally have no p-tags, but malformed/legacy
-- rows can. Serve defensive mention cleanup without a per-replacement seq scan.
CREATE INDEX idx_event_mentions_community_event
ON event_mentions (community_id, event_id);
-- Fail closed on legacy anomalies that would make a deleted tuple outrank a
-- live head. Seeding that tuple would freeze legitimate writes; ignoring it
-- would weaken replay protection. Operators must inspect and repair such a
-- coordinate before retrying the migration.
DO $$
BEGIN
IF EXISTS (
SELECT 1
FROM events dead
JOIN LATERAL (
SELECT live.created_at, live.id
FROM events live
WHERE live.community_id = dead.community_id
AND live.kind = dead.kind
AND live.pubkey = dead.pubkey
AND live.d_tag = dead.d_tag
AND live.deleted_at IS NULL
ORDER BY live.created_at DESC, live.id ASC
LIMIT 1
) live ON TRUE
WHERE dead.kind = 30078
AND dead.deleted_at IS NOT NULL
AND dead.d_tag ~ '^read-state:[0-9a-f]{32}$'
AND EXISTS (
SELECT 1
FROM jsonb_array_elements(dead.tags) tag
WHERE jsonb_typeof(tag) = 'array'
AND jsonb_array_length(tag) = 2
AND tag->>0 = 't'
AND tag->>1 = 'read-state'
)
AND (dead.created_at > live.created_at
OR (dead.created_at = live.created_at AND dead.id < live.id))
) THEN
RAISE EXCEPTION 'NIP-RS retention blocked: deleted event outranks live head';
END IF;
END $$;
-- Seed the greatest accepted tuple (newest created_at; lowest id wins ties)
-- from live and historical NIP-RS rows before removing payload history.
INSERT INTO parameterized_event_watermarks
(community_id, kind, pubkey, d_tag, created_at, event_id)
SELECT DISTINCT ON (community_id, kind, pubkey, d_tag)
community_id, kind, pubkey, d_tag, created_at, id
FROM events e
WHERE kind = 30078
AND d_tag ~ '^read-state:[0-9a-f]{32}$'
AND EXISTS (
SELECT 1
FROM jsonb_array_elements(e.tags) tag
WHERE jsonb_typeof(tag) = 'array'
AND jsonb_array_length(tag) = 2
AND tag->>0 = 't'
AND tag->>1 = 'read-state'
)
ORDER BY community_id, kind, pubkey, d_tag, created_at DESC, id ASC;
-- Mentions are denormalized and do not have a foreign key to the partitioned
-- events table. Delete any defensive/legacy rows for the exact purge set first.
DELETE FROM event_mentions mention
USING events old
WHERE mention.community_id = old.community_id
AND mention.event_id = old.id
AND mention.event_created_at = old.created_at
AND old.kind = 30078
AND old.deleted_at IS NOT NULL
AND old.d_tag ~ '^read-state:[0-9a-f]{32}$'
AND EXISTS (
SELECT 1
FROM jsonb_array_elements(old.tags) tag
WHERE jsonb_typeof(tag) = 'array'
AND jsonb_array_length(tag) = 2
AND tag->>0 = 't'
AND tag->>1 = 'read-state'
)
AND EXISTS (
SELECT 1
FROM events live
WHERE live.community_id = old.community_id
AND live.kind = old.kind
AND live.pubkey = old.pubkey
AND live.d_tag = old.d_tag
AND live.deleted_at IS NULL
AND (live.created_at > old.created_at
OR (live.created_at = old.created_at AND live.id < old.id))
);
-- Purge only replacement history with a strictly dominating live head. Rows
-- deleted explicitly through NIP-09 have no live head and remain untouched.
DELETE FROM events old
WHERE old.kind = 30078
AND old.deleted_at IS NOT NULL
AND old.d_tag ~ '^read-state:[0-9a-f]{32}$'
AND EXISTS (
SELECT 1
FROM jsonb_array_elements(old.tags) tag
WHERE jsonb_typeof(tag) = 'array'
AND jsonb_array_length(tag) = 2
AND tag->>0 = 't'
AND tag->>1 = 'read-state'
)
AND EXISTS (
SELECT 1
FROM events live
WHERE live.community_id = old.community_id
AND live.kind = old.kind
AND live.pubkey = old.pubkey
AND live.d_tag = old.d_tag
AND live.deleted_at IS NULL
AND (live.created_at > old.created_at
OR (live.created_at = old.created_at AND live.id < old.id))
);