mirror of
https://github.com/block/buzz.git
synced 2026-11-01 06:51:17 +00:00
Cumulative PR layer #4847. Installs the reviewed provider-neutral relay authorization runtime, crash-recoverable current-status delivery, protected-ingress production composition, canonical mutation ordering, and exact runtime-contract regressions. A configured required identity gate remains fail-closed when its retired compatibility verifier is unavailable. Neighbor disclosure: canonical database/operator authority remains owned by the lower layers, while the core status contract is owned by #4790 and native desktop consumption remains in #4987. Signed-off-by: Cea Stapleton Cordasco <261786559+cea@users.noreply.github.com>
256 lines
12 KiB
PL/PgSQL
256 lines
12 KiB
PL/PgSQL
-- Reconcile the crash-durable journal with the accepted S5 rule that status
|
|
-- revisions and withdrawals are scoped to one exact connection generation.
|
|
-- The relay producer did not exist before this migration, so any transition
|
|
-- row would be evidence of an unsupported writer and must stop rollout.
|
|
|
|
LOCK TABLE client_status_transitions, client_status_transition_heads,
|
|
client_status_delivery_outbox IN ACCESS EXCLUSIVE MODE;
|
|
|
|
DO $$
|
|
BEGIN
|
|
IF EXISTS (SELECT 1 FROM client_status_transitions) THEN
|
|
RAISE EXCEPTION 'client status connection-scope migration requires an empty journal'
|
|
USING ERRCODE = 'object_not_in_prerequisite_state';
|
|
END IF;
|
|
END;
|
|
$$;
|
|
|
|
-- A status authorization holds FOR SHARE on the same community row until the
|
|
-- physical writer acknowledgement is durably completed. Every newer policy
|
|
-- revision therefore waits only for status flushes in its own tenant.
|
|
CREATE OR REPLACE FUNCTION client_status_policy_connection_fence_v1() RETURNS TRIGGER AS $$
|
|
BEGIN
|
|
PERFORM id FROM communities WHERE id=NEW.community_id FOR UPDATE;
|
|
IF NOT FOUND THEN
|
|
RAISE EXCEPTION 'client status policy community is unavailable'
|
|
USING ERRCODE = 'foreign_key_violation';
|
|
END IF;
|
|
RETURN NEW;
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
|
|
CREATE TRIGGER client_status_policy_connection_fence
|
|
BEFORE INSERT ON identity_enrollment_policies
|
|
FOR EACH ROW EXECUTE FUNCTION client_status_policy_connection_fence_v1();
|
|
|
|
ALTER TABLE client_status_transitions
|
|
ADD COLUMN connection_fingerprint BYTEA NOT NULL CHECK (
|
|
octet_length(connection_fingerprint) = 32
|
|
AND connection_fingerprint <> decode(repeat('00', 32), 'hex')
|
|
),
|
|
ADD COLUMN evidence_author_pubkey BYTEA CHECK (
|
|
evidence_author_pubkey IS NULL OR octet_length(evidence_author_pubkey) = 32
|
|
),
|
|
ADD COLUMN evidence_binding_id UUID,
|
|
ADD COLUMN evidence_binding_version BIGINT CHECK (
|
|
evidence_binding_version IS NULL OR evidence_binding_version > 0
|
|
),
|
|
ADD COLUMN evidence_policy_revision BIGINT CHECK (
|
|
evidence_policy_revision IS NULL OR evidence_policy_revision > 0
|
|
),
|
|
ADD COLUMN evidence_invalidation_generation BIGINT CHECK (
|
|
evidence_invalidation_generation IS NULL OR evidence_invalidation_generation >= 0
|
|
),
|
|
ADD COLUMN evidence_authority_epoch BIGINT CHECK (
|
|
evidence_authority_epoch IS NULL OR evidence_authority_epoch > 0
|
|
),
|
|
ADD COLUMN evidence_fence BYTEA CHECK (
|
|
evidence_fence IS NULL
|
|
OR (octet_length(evidence_fence) = 32
|
|
AND evidence_fence <> decode(repeat('00', 32), 'hex'))
|
|
),
|
|
ADD COLUMN evidence_observed_at TIMESTAMPTZ,
|
|
ADD CONSTRAINT client_status_transition_private_evidence CHECK (
|
|
(delivery_kind = 1
|
|
AND evidence_author_pubkey IS NOT NULL
|
|
AND evidence_binding_id IS NOT NULL
|
|
AND evidence_binding_id <> '00000000-0000-0000-0000-000000000000'::uuid
|
|
AND evidence_binding_version IS NOT NULL
|
|
AND evidence_policy_revision IS NOT NULL
|
|
AND evidence_invalidation_generation IS NOT NULL
|
|
AND evidence_authority_epoch IS NOT NULL
|
|
AND evidence_fence IS NOT NULL
|
|
AND evidence_observed_at IS NOT NULL
|
|
AND evidence_observed_at < fresh_until)
|
|
OR (delivery_kind = 2
|
|
AND evidence_author_pubkey IS NULL
|
|
AND evidence_binding_id IS NULL
|
|
AND evidence_binding_version IS NULL
|
|
AND evidence_policy_revision IS NULL
|
|
AND evidence_invalidation_generation IS NULL
|
|
AND evidence_authority_epoch IS NULL
|
|
AND evidence_fence IS NULL
|
|
AND evidence_observed_at IS NULL)
|
|
);
|
|
|
|
ALTER TABLE client_status_transition_heads
|
|
ADD COLUMN connection_fingerprint BYTEA NOT NULL CHECK (
|
|
octet_length(connection_fingerprint) = 32
|
|
AND connection_fingerprint <> decode(repeat('00', 32), 'hex')
|
|
);
|
|
|
|
ALTER TABLE client_status_transition_heads
|
|
DROP CONSTRAINT client_status_transition_heads_transition,
|
|
DROP CONSTRAINT client_status_transition_heads_pkey;
|
|
|
|
DO $$
|
|
DECLARE constraint_name TEXT;
|
|
BEGIN
|
|
SELECT c.conname INTO constraint_name
|
|
FROM pg_constraint c
|
|
WHERE c.conrelid = 'client_status_transition_heads'::regclass
|
|
AND c.contype = 'u'
|
|
AND pg_get_constraintdef(c.oid)
|
|
= 'UNIQUE (community_id, transition_id)';
|
|
IF constraint_name IS NOT NULL THEN
|
|
EXECUTE format(
|
|
'ALTER TABLE client_status_transition_heads DROP CONSTRAINT %I',
|
|
constraint_name
|
|
);
|
|
END IF;
|
|
|
|
SELECT c.conname INTO constraint_name
|
|
FROM pg_constraint c
|
|
WHERE c.conrelid = 'client_status_transitions'::regclass
|
|
AND c.contype = 'u'
|
|
AND pg_get_constraintdef(c.oid)
|
|
= 'UNIQUE (community_id, subject_fingerprint, signer_fingerprint, status_revision)';
|
|
IF constraint_name IS NOT NULL THEN
|
|
EXECUTE format(
|
|
'ALTER TABLE client_status_transitions DROP CONSTRAINT %I',
|
|
constraint_name
|
|
);
|
|
END IF;
|
|
|
|
SELECT c.conname INTO constraint_name
|
|
FROM pg_constraint c
|
|
WHERE c.conrelid = 'client_status_transitions'::regclass
|
|
AND c.contype = 'u'
|
|
AND pg_get_constraintdef(c.oid)
|
|
= 'UNIQUE (community_id, transition_id, subject_fingerprint, signer_fingerprint, status_revision, delivery_kind)';
|
|
IF constraint_name IS NOT NULL THEN
|
|
EXECUTE format(
|
|
'ALTER TABLE client_status_transitions DROP CONSTRAINT %I',
|
|
constraint_name
|
|
);
|
|
END IF;
|
|
END;
|
|
$$;
|
|
|
|
ALTER TABLE client_status_transitions
|
|
ADD CONSTRAINT client_status_transition_connection_revision
|
|
UNIQUE (community_id, connection_fingerprint, status_revision),
|
|
ADD CONSTRAINT client_status_transition_connection_identity
|
|
UNIQUE (community_id, transition_id, connection_fingerprint,
|
|
subject_fingerprint, signer_fingerprint, status_revision, delivery_kind);
|
|
|
|
ALTER TABLE client_status_transition_heads
|
|
ADD PRIMARY KEY (community_id, connection_fingerprint),
|
|
ADD UNIQUE (community_id, transition_id, connection_fingerprint),
|
|
ADD CONSTRAINT client_status_transition_heads_transition
|
|
FOREIGN KEY (community_id, transition_id, connection_fingerprint,
|
|
subject_fingerprint, signer_fingerprint, status_revision, delivery_kind)
|
|
REFERENCES client_status_transitions
|
|
(community_id, transition_id, connection_fingerprint,
|
|
subject_fingerprint, signer_fingerprint, status_revision, delivery_kind)
|
|
DEFERRABLE INITIALLY DEFERRED;
|
|
|
|
CREATE OR REPLACE FUNCTION client_status_transition_head_guard_v1() RETURNS TRIGGER AS $$
|
|
BEGIN
|
|
IF TG_OP = 'INSERT' THEN
|
|
IF NEW.status_revision <> 1 THEN
|
|
RAISE EXCEPTION 'client status head must start at revision one'
|
|
USING ERRCODE = 'check_violation', CONSTRAINT = 'client_status_transition_head_revision';
|
|
END IF;
|
|
ELSIF NEW.community_id IS DISTINCT FROM OLD.community_id
|
|
OR NEW.connection_fingerprint IS DISTINCT FROM OLD.connection_fingerprint
|
|
OR NEW.subject_fingerprint IS DISTINCT FROM OLD.subject_fingerprint
|
|
OR NEW.signer_fingerprint IS DISTINCT FROM OLD.signer_fingerprint
|
|
OR NEW.status_revision <> OLD.status_revision + 1
|
|
OR NEW.transition_id IS NOT DISTINCT FROM OLD.transition_id
|
|
THEN
|
|
RAISE EXCEPTION 'client status head transition is invalid'
|
|
USING ERRCODE = 'check_violation', CONSTRAINT = 'client_status_transition_head_revision';
|
|
END IF;
|
|
NEW.updated_at := transaction_timestamp();
|
|
RETURN NEW;
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
|
|
CREATE OR REPLACE FUNCTION client_status_delivery_state_guard_v1() RETURNS TRIGGER AS $$
|
|
DECLARE claim_advance BOOLEAN; retry_advance BOOLEAN; delivered_advance BOOLEAN; terminal_advance BOOLEAN;
|
|
DECLARE expired_transition BOOLEAN; stale_transition BOOLEAN;
|
|
BEGIN
|
|
IF NEW.community_id IS DISTINCT FROM OLD.community_id
|
|
OR NEW.delivery_id IS DISTINCT FROM OLD.delivery_id
|
|
OR NEW.transition_id IS DISTINCT FROM OLD.transition_id
|
|
OR NEW.connection_fingerprint IS DISTINCT FROM OLD.connection_fingerprint
|
|
OR NEW.created_at IS DISTINCT FROM OLD.created_at
|
|
OR NEW.retain_until IS DISTINCT FROM OLD.retain_until
|
|
OR OLD.delivery_state <> 1
|
|
THEN
|
|
RAISE EXCEPTION 'client status delivery transition is invalid'
|
|
USING ERRCODE = 'check_violation', CONSTRAINT = 'client_status_delivery_transition';
|
|
END IF;
|
|
SELECT EXISTS(SELECT 1 FROM client_status_transitions transition
|
|
WHERE transition.community_id=OLD.community_id
|
|
AND transition.transition_id=OLD.transition_id
|
|
AND transition.fresh_until <= transaction_timestamp())
|
|
INTO expired_transition;
|
|
SELECT NOT EXISTS(
|
|
SELECT 1 FROM client_status_delivery_outbox delivery
|
|
JOIN client_status_transitions transition
|
|
ON transition.community_id=delivery.community_id
|
|
AND transition.transition_id=delivery.transition_id
|
|
JOIN client_status_transition_heads head
|
|
ON head.community_id=transition.community_id
|
|
AND head.connection_fingerprint=delivery.connection_fingerprint
|
|
AND head.transition_id=transition.transition_id
|
|
WHERE delivery.community_id=OLD.community_id
|
|
AND delivery.delivery_id=OLD.delivery_id)
|
|
INTO stale_transition;
|
|
claim_advance := NEW.delivery_state = 1 AND NEW.claim_id IS NOT NULL
|
|
AND NEW.completion_claim_id IS NULL AND NEW.attempt_count = OLD.attempt_count + 1
|
|
AND NOT stale_transition AND NOT expired_transition
|
|
AND OLD.next_attempt_at <= transaction_timestamp() AND OLD.attempt_count < 16
|
|
AND (OLD.claim_id IS NULL OR OLD.claimed_until <= transaction_timestamp())
|
|
AND NEW.claim_id IS DISTINCT FROM OLD.claim_id
|
|
AND NEW.claimed_until > transaction_timestamp()
|
|
AND NEW.claimed_until <= transaction_timestamp() + INTERVAL '5 minutes'
|
|
AND NEW.attempt_started_at IS NOT NULL
|
|
AND (NEW.last_failure_reason = OLD.last_failure_reason
|
|
OR (OLD.claim_id IS NOT NULL AND OLD.claimed_until <= transaction_timestamp()
|
|
AND NEW.last_failure_reason = 7))
|
|
AND NEW.next_attempt_at = OLD.next_attempt_at;
|
|
retry_advance := NEW.delivery_state = 1 AND OLD.claim_id IS NOT NULL AND NEW.claim_id IS NULL
|
|
AND NEW.completion_claim_id IS NULL AND NEW.attempt_count = OLD.attempt_count
|
|
AND NEW.attempt_started_at = OLD.attempt_started_at AND NEW.last_failure_reason = 1
|
|
AND NEW.next_attempt_at > OLD.next_attempt_at;
|
|
delivered_advance := NEW.delivery_state = 2 AND OLD.claim_id IS NOT NULL
|
|
AND NEW.claim_id IS NULL AND NEW.completion_claim_id = OLD.claim_id
|
|
AND NEW.attempt_count = OLD.attempt_count AND NEW.delivered_at IS NOT NULL
|
|
AND NEW.terminal_at IS NULL AND NEW.last_failure_reason = 0;
|
|
terminal_advance := NEW.delivery_state = 3 AND NEW.claim_id IS NULL
|
|
AND NEW.completion_claim_id IS NOT NULL
|
|
AND NEW.attempt_count = OLD.attempt_count AND NEW.delivered_at IS NULL
|
|
AND NEW.terminal_at IS NOT NULL
|
|
AND (
|
|
(OLD.claim_id IS NOT NULL AND NEW.completion_claim_id = OLD.claim_id
|
|
AND NEW.last_failure_reason BETWEEN 2 AND 7)
|
|
OR (NEW.last_failure_reason = 2
|
|
AND (OLD.claim_id IS NULL OR NEW.completion_claim_id = OLD.claim_id))
|
|
OR (NEW.last_failure_reason = 3 AND stale_transition
|
|
AND (OLD.claim_id IS NULL OR OLD.claimed_until <= transaction_timestamp()))
|
|
OR (NEW.last_failure_reason = 5 AND expired_transition
|
|
AND (OLD.claim_id IS NULL OR OLD.claimed_until <= transaction_timestamp()))
|
|
OR (NEW.last_failure_reason = 6 AND OLD.attempt_count >= 16
|
|
AND (OLD.claim_id IS NULL OR OLD.claimed_until <= transaction_timestamp()))
|
|
);
|
|
IF NOT (claim_advance OR retry_advance OR delivered_advance OR terminal_advance) THEN
|
|
RAISE EXCEPTION 'client status delivery transition is invalid'
|
|
USING ERRCODE = 'check_violation', CONSTRAINT = 'client_status_delivery_transition';
|
|
END IF;
|
|
RETURN NEW;
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|