radrootsd

JSON-RPC bridge for Radroots event publishing
git clone https://radroots.dev/git/radrootsd.git
Log | Files | Refs | README | LICENSE

commit a17f4c71f3bf838a9d3c9677354ac17ab4d11158
parent 516f80c21e847e1c8868eff426641692ac68dd56
Author: triesap <tyson@radroots.org>
Date:   Wed,  8 Jul 2026 05:01:31 +0000

transport: prove duplicate explicit targets fail

- add daemon publish coverage for duplicate explicit target requests
- assert shared validation fails before publish job recording
- keep relay publishing untouched when duplicate targets are rejected
- verify storage remains empty for invalid duplicate ingress

Diffstat:
Msrc/core/transport_publish.rs | 37+++++++++++++++++++++++++++++++++++++
1 file changed, 37 insertions(+), 0 deletions(-)

diff --git a/src/core/transport_publish.rs b/src/core/transport_publish.rs @@ -3459,6 +3459,43 @@ mod tests { } #[tokio::test] + async fn publish_event_rejects_duplicate_explicit_targets_before_recording_job() { + let identity = RadrootsIdentity::generate(); + let (proxy, adapter) = transport_publish(config_with_defaults(vec![RELAY_PRIMARY])); + let principal = + explicit_target_principal(&proxy, identity.public_key_hex(), PublishJobVisibility::Own); + let request = TransportPublishEventRequest { + event: signed_event(&identity, "{}"), + target_policy: TransportPublishTargetPolicy::explicit_targets(vec![ + TransportPublishTarget::nostr(RELAY_PRIMARY), + TransportPublishTarget::nostr(RELAY_PRIMARY), + ]), + delivery_policy: TransportPublishDeliveryPolicy::Any, + idempotency_key: None, + timeout_ms: Some(5_000), + }; + + let err = proxy + .publish_event(&principal, request) + .await + .expect_err("duplicate explicit targets"); + + assert!(matches!( + err, + TransportPublishError::InvalidSignedEvent(ref message) + if message.contains("duplicates an earlier target") + )); + assert!(adapter.captured_raw_events().is_empty()); + assert!( + proxy + .store + .list_jobs_for_principal(&principal, 10) + .expect("jobs") + .is_empty() + ); + } + + #[tokio::test] async fn publish_event_rejects_explicit_target_kind_not_allowed_before_recording_job() { let identity = RadrootsIdentity::generate(); let (proxy, adapter) = transport_publish(TransportPublishConfig::default());