commit 6cd7c92bc95e2c3b42749b98798ffff89909a177
parent 10c59915a365e89e5e2bae8efd5a549c4d818a96
Author: triesap <tyson@radroots.org>
Date: Wed, 5 Aug 2026 14:48:08 +0000
refactor: adopt canonical transport delivery policy
- pin daemon dependencies to the final authored-operations lib revision
- remove duplicate satisfaction policy state from the relay adapter
- preserve exact V5 target, SSRF, idempotency, and persistence behavior
- qualify locked checks, tests, Clippy, docs, and package payloads
Diffstat:
5 files changed, 29 insertions(+), 121 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
@@ -1604,7 +1604,7 @@ checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
[[package]]
name = "radroots_blossom"
version = "0.1.0-alpha"
-source = "git+https://github.com/radrootslabs/lib.git?rev=74f5c91cbc80248df1f51f644004daaf8ae8e9be#74f5c91cbc80248df1f51f644004daaf8ae8e9be"
+source = "git+https://github.com/radrootslabs/lib.git?rev=691b3c844bb8824fd16b2ff4fb37b8c09bac208d#691b3c844bb8824fd16b2ff4fb37b8c09bac208d"
dependencies = [
"mediatype",
"serde",
@@ -1616,7 +1616,7 @@ dependencies = [
[[package]]
name = "radroots_core"
version = "0.1.0-alpha"
-source = "git+https://github.com/radrootslabs/lib.git?rev=74f5c91cbc80248df1f51f644004daaf8ae8e9be#74f5c91cbc80248df1f51f644004daaf8ae8e9be"
+source = "git+https://github.com/radrootslabs/lib.git?rev=691b3c844bb8824fd16b2ff4fb37b8c09bac208d#691b3c844bb8824fd16b2ff4fb37b8c09bac208d"
dependencies = [
"rust_decimal",
"serde",
@@ -1625,7 +1625,7 @@ dependencies = [
[[package]]
name = "radroots_event"
version = "0.1.0-alpha"
-source = "git+https://github.com/radrootslabs/lib.git?rev=74f5c91cbc80248df1f51f644004daaf8ae8e9be#74f5c91cbc80248df1f51f644004daaf8ae8e9be"
+source = "git+https://github.com/radrootslabs/lib.git?rev=691b3c844bb8824fd16b2ff4fb37b8c09bac208d#691b3c844bb8824fd16b2ff4fb37b8c09bac208d"
dependencies = [
"hex",
"jiff-tzdb",
@@ -1643,8 +1643,9 @@ dependencies = [
[[package]]
name = "radroots_event_codec"
version = "0.1.0-alpha"
-source = "git+https://github.com/radrootslabs/lib.git?rev=74f5c91cbc80248df1f51f644004daaf8ae8e9be#74f5c91cbc80248df1f51f644004daaf8ae8e9be"
+source = "git+https://github.com/radrootslabs/lib.git?rev=691b3c844bb8824fd16b2ff4fb37b8c09bac208d#691b3c844bb8824fd16b2ff4fb37b8c09bac208d"
dependencies = [
+ "hex",
"radroots_blossom",
"radroots_core",
"radroots_event",
@@ -1653,12 +1654,13 @@ dependencies = [
"secp256k1",
"serde",
"serde_json",
+ "sha2",
]
[[package]]
name = "radroots_identity"
version = "0.1.0-alpha"
-source = "git+https://github.com/radrootslabs/lib.git?rev=74f5c91cbc80248df1f51f644004daaf8ae8e9be#74f5c91cbc80248df1f51f644004daaf8ae8e9be"
+source = "git+https://github.com/radrootslabs/lib.git?rev=691b3c844bb8824fd16b2ff4fb37b8c09bac208d#691b3c844bb8824fd16b2ff4fb37b8c09bac208d"
dependencies = [
"k256",
"serde",
@@ -1668,7 +1670,7 @@ dependencies = [
[[package]]
name = "radroots_nostr"
version = "0.1.0-alpha"
-source = "git+https://github.com/radrootslabs/lib.git?rev=74f5c91cbc80248df1f51f644004daaf8ae8e9be#74f5c91cbc80248df1f51f644004daaf8ae8e9be"
+source = "git+https://github.com/radrootslabs/lib.git?rev=691b3c844bb8824fd16b2ff4fb37b8c09bac208d#691b3c844bb8824fd16b2ff4fb37b8c09bac208d"
dependencies = [
"nostr",
"radroots_event",
@@ -1682,7 +1684,7 @@ dependencies = [
[[package]]
name = "radroots_protocol"
version = "0.1.0-alpha"
-source = "git+https://github.com/radrootslabs/lib.git?rev=74f5c91cbc80248df1f51f644004daaf8ae8e9be#74f5c91cbc80248df1f51f644004daaf8ae8e9be"
+source = "git+https://github.com/radrootslabs/lib.git?rev=691b3c844bb8824fd16b2ff4fb37b8c09bac208d#691b3c844bb8824fd16b2ff4fb37b8c09bac208d"
dependencies = [
"serde",
]
@@ -1690,7 +1692,7 @@ dependencies = [
[[package]]
name = "radroots_secrets"
version = "0.1.0-alpha"
-source = "git+https://github.com/radrootslabs/lib.git?rev=74f5c91cbc80248df1f51f644004daaf8ae8e9be#74f5c91cbc80248df1f51f644004daaf8ae8e9be"
+source = "git+https://github.com/radrootslabs/lib.git?rev=691b3c844bb8824fd16b2ff4fb37b8c09bac208d#691b3c844bb8824fd16b2ff4fb37b8c09bac208d"
dependencies = [
"chacha20poly1305",
"zeroize",
@@ -1699,7 +1701,7 @@ dependencies = [
[[package]]
name = "radroots_transport"
version = "0.1.0-alpha"
-source = "git+https://github.com/radrootslabs/lib.git?rev=74f5c91cbc80248df1f51f644004daaf8ae8e9be#74f5c91cbc80248df1f51f644004daaf8ae8e9be"
+source = "git+https://github.com/radrootslabs/lib.git?rev=691b3c844bb8824fd16b2ff4fb37b8c09bac208d#691b3c844bb8824fd16b2ff4fb37b8c09bac208d"
dependencies = [
"radroots_event",
"radroots_identity",
@@ -1710,7 +1712,7 @@ dependencies = [
[[package]]
name = "radroots_transport_nostr"
version = "0.1.0-alpha"
-source = "git+https://github.com/radrootslabs/lib.git?rev=74f5c91cbc80248df1f51f644004daaf8ae8e9be#74f5c91cbc80248df1f51f644004daaf8ae8e9be"
+source = "git+https://github.com/radrootslabs/lib.git?rev=691b3c844bb8824fd16b2ff4fb37b8c09bac208d#691b3c844bb8824fd16b2ff4fb37b8c09bac208d"
dependencies = [
"async-wsocket",
"nostr-relay-pool",
diff --git a/Cargo.toml b/Cargo.toml
@@ -11,14 +11,14 @@ description = "Radroots local runtime daemon for storage, sync, and relay publis
resolver = "3"
[workspace.dependencies]
-radroots_event = { git = "https://github.com/radrootslabs/lib.git", rev = "74f5c91cbc80248df1f51f644004daaf8ae8e9be", version = "=0.1.0-alpha" }
-radroots_event_codec = { git = "https://github.com/radrootslabs/lib.git", rev = "74f5c91cbc80248df1f51f644004daaf8ae8e9be", version = "=0.1.0-alpha" }
-radroots_identity = { git = "https://github.com/radrootslabs/lib.git", rev = "74f5c91cbc80248df1f51f644004daaf8ae8e9be", version = "=0.1.0-alpha" }
-radroots_nostr = { git = "https://github.com/radrootslabs/lib.git", rev = "74f5c91cbc80248df1f51f644004daaf8ae8e9be", version = "=0.1.0-alpha" }
-radroots_protocol = { git = "https://github.com/radrootslabs/lib.git", rev = "74f5c91cbc80248df1f51f644004daaf8ae8e9be", version = "=0.1.0-alpha", default-features = false }
-radroots_secrets = { git = "https://github.com/radrootslabs/lib.git", rev = "74f5c91cbc80248df1f51f644004daaf8ae8e9be", version = "=0.1.0-alpha", default-features = false }
-radroots_transport_nostr = { git = "https://github.com/radrootslabs/lib.git", rev = "74f5c91cbc80248df1f51f644004daaf8ae8e9be", version = "=0.1.0-alpha", default-features = false }
-radroots_transport = { git = "https://github.com/radrootslabs/lib.git", rev = "74f5c91cbc80248df1f51f644004daaf8ae8e9be", version = "=0.1.0-alpha", default-features = false }
+radroots_event = { git = "https://github.com/radrootslabs/lib.git", rev = "691b3c844bb8824fd16b2ff4fb37b8c09bac208d", version = "=0.1.0-alpha" }
+radroots_event_codec = { git = "https://github.com/radrootslabs/lib.git", rev = "691b3c844bb8824fd16b2ff4fb37b8c09bac208d", version = "=0.1.0-alpha" }
+radroots_identity = { git = "https://github.com/radrootslabs/lib.git", rev = "691b3c844bb8824fd16b2ff4fb37b8c09bac208d", version = "=0.1.0-alpha" }
+radroots_nostr = { git = "https://github.com/radrootslabs/lib.git", rev = "691b3c844bb8824fd16b2ff4fb37b8c09bac208d", version = "=0.1.0-alpha" }
+radroots_protocol = { git = "https://github.com/radrootslabs/lib.git", rev = "691b3c844bb8824fd16b2ff4fb37b8c09bac208d", version = "=0.1.0-alpha", default-features = false }
+radroots_secrets = { git = "https://github.com/radrootslabs/lib.git", rev = "691b3c844bb8824fd16b2ff4fb37b8c09bac208d", version = "=0.1.0-alpha", default-features = false }
+radroots_transport_nostr = { git = "https://github.com/radrootslabs/lib.git", rev = "691b3c844bb8824fd16b2ff4fb37b8c09bac208d", version = "=0.1.0-alpha", default-features = false }
+radroots_transport = { git = "https://github.com/radrootslabs/lib.git", rev = "691b3c844bb8824fd16b2ff4fb37b8c09bac208d", version = "=0.1.0-alpha", default-features = false }
[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(coverage_nightly)'] }
diff --git a/src/core/transport_publish.rs b/src/core/transport_publish.rs
@@ -27,8 +27,7 @@ use radroots_protocol::radrootsd::transport_publish::v5::{
TargetSource,
};
use radroots_transport::{
- RadrootsTransportSatisfactionClass, RadrootsTransportSatisfactionPolicy,
- Target as TransportTarget, TransportId,
+ Error as TransportError, Target as TransportTarget, TransportId,
target::{TargetFingerprint, TargetLabel, TargetScope},
};
use serde::{Deserialize, Serialize};
@@ -616,15 +615,9 @@ impl TransportPublish {
.collect(),
)
.map_err(|error| TransportPublishError::Relay(error.to_string()))?;
- let satisfaction_policy = satisfaction_policy_from_delivery_policy(
- &delivery_policy,
- target_count,
- resolution.targets.as_slice(),
- )?;
let publish_relays = target_set.relays().to_vec();
let publish_request =
- RadrootsRelayPublishRequest::new(signed_event, target_set, current_unix_millis())
- .with_satisfaction_policy(satisfaction_policy);
+ RadrootsRelayPublishRequest::new(signed_event, target_set, current_unix_millis());
let started = Instant::now();
let publish_timeout = Duration::from_millis(timeout_ms);
let receipts =
@@ -2852,14 +2845,14 @@ fn transport_target_from_outcome_parts(
endpoint_uri: &str,
scope: Option<TargetScope>,
label: Option<TargetLabel>,
-) -> Result<TransportTarget, radroots_transport::RadrootsTransportError> {
+) -> Result<TransportTarget, TransportError> {
match transport_kind {
TransportId::NOSTR => {
TransportTarget::nostr_relay_with_metadata(endpoint_uri, scope, label)
}
TransportId::RETICULUM => {
if endpoint_uri != RADROOTS_RETICULUM_ENDPOINT_URI {
- return Err(radroots_transport::RadrootsTransportError::InvalidTargetUri);
+ return Err(TransportError::InvalidTargetUri);
}
let scope = match scope {
Some(scope) => scope,
@@ -2873,7 +2866,7 @@ fn transport_target_from_outcome_parts(
)
}
TransportId::LOCAL => TransportTarget::local_with_metadata(endpoint_uri, scope, label),
- _ => Err(radroots_transport::RadrootsTransportError::InvalidTargetUri),
+ _ => Err(TransportError::InvalidTargetUri),
}
}
@@ -2914,45 +2907,6 @@ fn required_outcomes_for_policy<'a>(
.collect()
}
-fn satisfaction_policy_from_delivery_policy(
- delivery_policy: &DeliveryPolicy,
- target_count: usize,
- nostr_targets: &[ResolvedPublishRelay],
-) -> Result<RadrootsTransportSatisfactionPolicy, TransportPublishError> {
- match delivery_policy {
- DeliveryPolicy::Any => Ok(RadrootsTransportSatisfactionPolicy::any_accepted()),
- DeliveryPolicy::All => Ok(RadrootsTransportSatisfactionPolicy::all_accepted()),
- DeliveryPolicy::Quorum { quorum } => {
- let required = (*quorum).min(target_count).min(nostr_targets.len()).max(1);
- Ok(RadrootsTransportSatisfactionPolicy::quorum_accepted(
- u16::try_from(required).unwrap_or(u16::MAX),
- ))
- }
- DeliveryPolicy::RequiredTargets { targets } => {
- let nostr_required_targets = targets
- .iter()
- .filter_map(|required| {
- nostr_targets.iter().find_map(|target| {
- target
- .fingerprint()
- .ok()
- .filter(|fingerprint| fingerprint.as_str() == required.as_str())
- })
- })
- .collect::<Vec<_>>();
- if nostr_required_targets.is_empty() {
- Ok(RadrootsTransportSatisfactionPolicy::no_wait())
- } else {
- Ok(RadrootsTransportSatisfactionPolicy::required_targets(
- RadrootsTransportSatisfactionClass::Accepted,
- nostr_required_targets,
- )
- .map_err(|error| TransportPublishError::Transport(error.to_string()))?)
- }
- }
- }
-}
-
fn delivery_status(
delivery_policy: &DeliveryPolicy,
target_count: usize,
diff --git a/src/transport/relay_publish.rs b/src/transport/relay_publish.rs
@@ -11,7 +11,6 @@ use std::sync::{Arc, Mutex};
use nostr::JsonUtil;
use radroots_event::SignedEvent;
-use radroots_transport::RadrootsTransportSatisfactionPolicy;
use crate::host_nostr::DaemonNostrClient;
@@ -89,7 +88,6 @@ impl RelayTargetSet {
pub(crate) struct RelayPublishRequest {
signed_event: SignedEvent,
targets: RelayTargetSet,
- satisfaction_policy: RadrootsTransportSatisfactionPolicy,
now_ms: i64,
}
@@ -98,18 +96,9 @@ impl RelayPublishRequest {
Self {
signed_event,
targets,
- satisfaction_policy: RadrootsTransportSatisfactionPolicy::all_accepted(),
now_ms,
}
}
-
- pub(crate) fn with_satisfaction_policy(
- mut self,
- satisfaction_policy: RadrootsTransportSatisfactionPolicy,
- ) -> Self {
- self.satisfaction_policy = satisfaction_policy;
- self
- }
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
diff --git a/tests/source_boundary.rs b/tests/source_boundary.rs
@@ -198,7 +198,7 @@ fn transport_publish_sources_reject_removed_protocol_identifiers() {
}
assert!(
manifest_source.contains(
- "radroots_transport_nostr = { git = \"https://github.com/radrootslabs/lib.git\", rev = \"74f5c91cbc80248df1f51f644004daaf8ae8e9be\", version = \"=0.1.0-alpha\""
+ "radroots_transport_nostr = { git = \"https://github.com/radrootslabs/lib.git\", rev = \"691b3c844bb8824fd16b2ff4fb37b8c09bac208d\", version = \"=0.1.0-alpha\""
),
"Cargo.toml must pin radroots_transport_nostr to the approved Lib revision and exact version"
);
@@ -401,32 +401,10 @@ fn transport_publish_required_targets_stay_fingerprint_exact() {
);
}
- let satisfaction_arm = source_window(
- daemon_source.as_str(),
- "DeliveryPolicy::RequiredTargets { targets } => {",
- "fn delivery_status(",
+ assert!(
+ !daemon_source.contains("SatisfactionPolicy"),
+ "daemon V5 delivery policy must not be duplicated in the transport adapter"
);
- for required in [
- "let nostr_required_targets = targets",
- "target\n .fingerprint()",
- "filter(|fingerprint| fingerprint.as_str() == required.as_str())",
- "RadrootsTransportSatisfactionPolicy::required_targets(",
- ] {
- assert!(
- satisfaction_arm.contains(required),
- "daemon RequiredTargets resolution arm must retain exact fingerprint witness `{required}`"
- );
- }
- for forbidden in [
- "RadrootsTransportSatisfactionPolicy::all_accepted()",
- "RadrootsTransportSatisfactionPolicy::any_accepted()",
- "RadrootsTransportSatisfactionPolicy::quorum_accepted(",
- ] {
- assert!(
- !satisfaction_arm.contains(forbidden),
- "daemon RequiredTargets resolution arm must not lower to count policy `{forbidden}`"
- );
- }
use radroots_protocol::radrootsd::transport_publish::v5::{DeliveryPolicy, TargetFingerprint};
let target = TargetFingerprint::parse("a".repeat(64)).expect("fingerprint");
@@ -619,21 +597,6 @@ fn is_doc_surface(path: &Path) -> bool {
)
}
-fn source_window<'source>(
- source: &'source str,
- start_marker: &str,
- end_marker: &str,
-) -> &'source str {
- let start = source
- .find(start_marker)
- .unwrap_or_else(|| panic!("source must contain start marker `{start_marker}`"));
- let end = source[start..]
- .find(end_marker)
- .map(|index| start + index)
- .unwrap_or_else(|| panic!("source must contain end marker `{end_marker}`"));
- &source[start..end]
-}
-
fn contains_forbidden_concept(source: &str, pattern: &str) -> bool {
if !pattern.chars().all(is_rust_identifier_character) {
return source.contains(pattern);