tangle


git clone https://radroots.dev/git/tangle.git
Log | Files | Refs | README | LICENSE

commit 67c5b31222f00e0f55b4ea2f47109569fc8183da
parent 458c17d51c2c56e2141eba15c110c8705a579912
Author: triesap <tyson@radroots.org>
Date:   Sun, 14 Jun 2026 02:09:49 -0700

runtime: extract pocket conversion boundary

- move temporary Tangle and Pocket conversion helpers into pocket_conversion
- update base relay and group service code to use one conversion boundary
- keep the JSON bridge behavior unchanged for the mechanical split
- verify formatting, conversion tests, integration tests, and benchmark compile checks

Diffstat:
Mcrates/tangle_runtime/src/base_relay.rs | 40++++++----------------------------------
Mcrates/tangle_runtime/src/groups.rs | 2+-
Mcrates/tangle_runtime/src/lib.rs | 1+
Acrates/tangle_runtime/src/pocket_conversion.rs | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 61 insertions(+), 35 deletions(-)

diff --git a/crates/tangle_runtime/src/base_relay.rs b/crates/tangle_runtime/src/base_relay.rs @@ -1,24 +1,21 @@ use crate::errors::{BaseRelayError, ok_accepted, ok_rejected}; use crate::groups::GroupService; use crate::ops::BaseRelayReadinessState; +use crate::pocket_conversion::{ + pocket_event_id, pocket_event_to_tangle, tangle_event_to_pocket, tangle_filter_to_pocket, +}; use crate::relay::{ auth::BaseAuthState, live::{CloseResult, LiveSubscriptionSet}, }; -use std::{collections::BTreeSet, str}; +use std::collections::BTreeSet; use tangle_crypto::verify_event_signature; use tangle_groups::{ GroupAuthContext, GroupEventClass, GroupProjection, GroupRuntimeConfig, StoreOffset, validate_client_group_event_structure, }; -use tangle_protocol::{ - ClientMessage, Event, EventId, Filter, RelayMessage, SubscriptionId, UnixTimestamp, - event_to_value, filter_to_value, parse_event_json, -}; -use tangle_store_pocket::{ - PocketEvent, PocketEventId, PocketOwnedEvent, PocketOwnedFilter, PocketStoreConfig, - PocketStoreHandle, parse_pocket_event_json, parse_pocket_filter_json, -}; +use tangle_protocol::{ClientMessage, Event, Filter, RelayMessage, SubscriptionId, UnixTimestamp}; +use tangle_store_pocket::{PocketStoreConfig, PocketStoreHandle}; pub struct BaseRelay { store: PocketStoreHandle, @@ -345,31 +342,6 @@ impl BaseRelay { } } -pub(crate) fn tangle_event_to_pocket(event: &Event) -> Result<PocketOwnedEvent, BaseRelayError> { - let raw = event_to_value(event).to_string(); - parse_pocket_event_json(raw.as_bytes()).map_err(BaseRelayError::from) -} - -fn tangle_filter_to_pocket(filter: &Filter) -> Result<PocketOwnedFilter, BaseRelayError> { - let raw = filter_to_value(filter).to_string(); - parse_pocket_filter_json(raw.as_bytes()).map_err(BaseRelayError::from) -} - -pub(crate) fn pocket_event_to_tangle(event: &PocketEvent) -> Result<Event, BaseRelayError> { - let raw = event - .as_json() - .map_err(|error| BaseRelayError::error(error.to_string()))?; - let raw = str::from_utf8(&raw).map_err(|error| BaseRelayError::error(error.to_string()))?; - let raw = tangle_protocol::RawEventJson::new(raw) - .map_err(|error| BaseRelayError::error(error.to_string()))?; - parse_event_json(&raw).map_err(|error| BaseRelayError::error(error.to_string())) -} - -pub(crate) fn pocket_event_id(event_id: &EventId) -> Result<PocketEventId, BaseRelayError> { - PocketEventId::read_hex(event_id.as_str().as_bytes()) - .map_err(|error| BaseRelayError::error(error.to_string())) -} - #[cfg(test)] mod tests { use super::BaseRelay; diff --git a/crates/tangle_runtime/src/groups.rs b/crates/tangle_runtime/src/groups.rs @@ -1,8 +1,8 @@ #![forbid(unsafe_code)] use crate::{ - base_relay::{pocket_event_id, pocket_event_to_tangle, tangle_event_to_pocket}, errors::BaseRelayError, + pocket_conversion::{pocket_event_id, pocket_event_to_tangle, tangle_event_to_pocket}, }; use std::str; use tangle_crypto::RelaySigner; diff --git a/crates/tangle_runtime/src/lib.rs b/crates/tangle_runtime/src/lib.rs @@ -7,6 +7,7 @@ pub mod errors; pub mod groups; pub mod nip11; pub mod ops; +pub(crate) mod pocket_conversion; pub mod relay; use std::{fmt, fs, path::Path, path::PathBuf}; diff --git a/crates/tangle_runtime/src/pocket_conversion.rs b/crates/tangle_runtime/src/pocket_conversion.rs @@ -0,0 +1,53 @@ +#![forbid(unsafe_code)] + +use crate::errors::BaseRelayError; +use std::str; +use tangle_protocol::{Event, EventId, Filter, event_to_value, filter_to_value, parse_event_json}; +use tangle_store_pocket::{ + PocketEvent, PocketEventId, PocketOwnedEvent, PocketOwnedFilter, parse_pocket_event_json, + parse_pocket_filter_json, +}; + +pub(crate) fn tangle_event_to_pocket(event: &Event) -> Result<PocketOwnedEvent, BaseRelayError> { + let raw = event_to_value(event).to_string(); + parse_pocket_event_json(raw.as_bytes()).map_err(BaseRelayError::from) +} + +pub(crate) fn tangle_filter_to_pocket( + filter: &Filter, +) -> Result<PocketOwnedFilter, BaseRelayError> { + let raw = filter_to_value(filter).to_string(); + parse_pocket_filter_json(raw.as_bytes()).map_err(BaseRelayError::from) +} + +pub(crate) fn pocket_event_to_tangle(event: &PocketEvent) -> Result<Event, BaseRelayError> { + let raw = event + .as_json() + .map_err(|error| BaseRelayError::error(error.to_string()))?; + let raw = str::from_utf8(&raw).map_err(|error| BaseRelayError::error(error.to_string()))?; + let raw = tangle_protocol::RawEventJson::new(raw) + .map_err(|error| BaseRelayError::error(error.to_string()))?; + parse_event_json(&raw).map_err(|error| BaseRelayError::error(error.to_string())) +} + +pub(crate) fn pocket_event_id(event_id: &EventId) -> Result<PocketEventId, BaseRelayError> { + PocketEventId::read_hex(event_id.as_str().as_bytes()) + .map_err(|error| BaseRelayError::error(error.to_string())) +} + +#[cfg(test)] +mod tests { + use super::{pocket_event_id, pocket_event_to_tangle, tangle_event_to_pocket}; + use tangle_test_support::{FixtureKey, tangle_v2_event}; + + #[test] + fn pocket_event_conversion_round_trips_signed_events() { + let event = tangle_v2_event(FixtureKey::Member, 1_714_124_433, 1, Vec::new(), "hello") + .expect("event"); + let pocket = tangle_event_to_pocket(&event).expect("pocket"); + let converted = pocket_event_to_tangle(&pocket).expect("converted"); + + assert_eq!(converted, event); + pocket_event_id(event.id()).expect("event id"); + } +}