From 49401286ea7413f834197e6a5b221649e10e2ad8 Mon Sep 17 00:00:00 2001 From: DanConwayDev Date: Mon, 23 Feb 2026 11:36:45 +0000 Subject: fix: promote purgatory announcements after git sync copy path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a state event arrives and the required commits already exist in another maintainer's repo on the same relay, process_state_with_git_data copies the OIDs across and aligns refs — but never called process_purgatory_announcements for the target repos. Any announcement waiting in purgatory for that repo stayed there indefinitely. Fix: after process_state_with_git_data, call process_newly_available_git_data for each target repo (those that received copied OIDs) so purgatory announcements are promoted immediately. --- src/nostr/policy/state.rs | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'src') diff --git a/src/nostr/policy/state.rs b/src/nostr/policy/state.rs index 4bfb513..9ad72c2 100644 --- a/src/nostr/policy/state.rs +++ b/src/nostr/policy/state.rs @@ -1,3 +1,4 @@ +use std::collections::HashSet; use std::path::{Path, PathBuf}; use anyhow::{Context, Result}; @@ -192,6 +193,42 @@ impl StatePolicy { } } + // After copying OIDs to other owner repos, promote any purgatory announcements + // for those repos. This handles the case where two maintainers push to the same + // identifier on the same relay with identical commit hashes: the second maintainer's + // announcement sits in purgatory, and when their state event arrives the relay copies + // commits from the first maintainer's repo — but without this call the announcement + // would stay in purgatory indefinitely. + let local_relay = self.ctx.get_local_relay(); + let empty_oids: HashSet = HashSet::new(); + for announcement in &db_repo_data.announcements { + let target_repo_path = self.ctx.git_data_path.join(announcement.repo_path()); + if target_repo_path != repo_with_git_data { + // OIDs were copied to this repo by process_state_with_git_data; + // check if there's a purgatory announcement waiting for it. + if let Err(e) = crate::git::sync::process_newly_available_git_data( + &target_repo_path, + &empty_oids, + &self.ctx.database, + local_relay.as_ref(), + &self.ctx.purgatory, + &self.ctx.git_data_path, + None, + None, + ) + .await + { + tracing::warn!( + identifier = %state.identifier, + event_id = %event.id, + repo_path = %target_repo_path.display(), + error = %e, + "Failed to process purgatory announcements for target repo after git sync copy" + ); + } + } + } + // Event will be saved and broadcast by relay builder Ok(WritePolicyResult::Accept) } else { -- cgit v1.2.3