Skip to content

Commit

Permalink
pool: add RelayServiceFlags::GOSSIP flag
Browse files Browse the repository at this point in the history
* Remove `INBOX` and `OUTBOX` flags
* Use a single `urls` field in `BrokenDownFilters` for both inbox and outbox relays

Signed-off-by: Yuki Kishimoto <[email protected]>
  • Loading branch information
yukibtc committed Nov 22, 2024
1 parent b347ec0 commit a4ebf69
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 80 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
* nostr: add `nip17::extract_relay_list` and `nip17::extract_owned_relay_list` ([Yuki Kishimoto])
* database: add `NostrEventsDatabase` trait ([Yuki Kishimoto])
* pool: add relay reconnection and disconnection unit tests ([Yuki Kishimoto])
* pool: add `RelayServiceFlags::GOSSIP` flag ([Yuki Kishimoto])
* sdk: allow to specify relay pool notification channel size in `Options` ([Yuki Kishimoto])
* relay-builder: add `RelayTestOptions` ([Yuki Kishimoto])
* connect: add `NostrConnect::non_secure_set_user_public_key` ([Yuki Kishimoto])
Expand All @@ -107,6 +108,7 @@
* nostr: remove `Marker::Custom` variant ([Yuki Kishimoto])
* pool: remove `Relay::support_negentropy` ([Yuki Kishimoto])
* pool: remove `Error::NotConnectedStatusChanged` variant ([Yuki Kishimoto])
* pool: remove `INBOX` and `OUTBOX` flags ([Yuki Kishimoto])
* ffi: remove `CustomNostrDatabase` trait ([Yuki Kishimoto])

### Deprecated
Expand Down
4 changes: 2 additions & 2 deletions crates/nostr-relay-pool/src/pool/inner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,10 +301,10 @@ impl InnerRelayPool {
// Remove relay
let relay = relays.remove(&url).ok_or(Error::RelayNotFound)?;

// If NOT force, check if has INBOX or OUTBOX flags
// If NOT force, check if has GOSSIP flag
if !force {
let flags = relay.flags();
if flags.has_any(RelayServiceFlags::INBOX | RelayServiceFlags::OUTBOX) {
if flags.has_any(RelayServiceFlags::GOSSIP) {
// Remove READ, WRITE and DISCOVERY flags
flags.remove(
RelayServiceFlags::READ
Expand Down
5 changes: 3 additions & 2 deletions crates/nostr-relay-pool/src/pool/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,8 +200,9 @@ impl RelayPool {

/// Remove and disconnect relay
///
/// If the relay has `INBOX` or `OUTBOX` flags, it will not be removed from the pool and its
/// flags will be updated (remove `READ`, `WRITE` and `DISCOVERY` flags).
/// If the relay has [`RelayServiceFlags::GOSSIP`], it will not be removed from the pool and its
/// flags will be updated (remove [`RelayServiceFlags::READ`],
/// [`RelayServiceFlags::WRITE`] and [`RelayServiceFlags::DISCOVERY`] flags).
#[inline]
pub async fn remove_relay<U>(&self, url: U) -> Result<(), Error>
where
Expand Down
59 changes: 21 additions & 38 deletions crates/nostr-relay-pool/src/relay/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,13 @@ impl RelayServiceFlags {
/// PING means that client will ping relay to keep connection up.
pub const PING: Self = Self(1 << 2); // 4

/// INBOX means automatically added relay that will perform read operations (READ of kind 10002).
pub const INBOX: Self = Self(1 << 3); // 8
/// GOSSIP means automatically added relay that will perform read/write operations.
///
/// Use for NIP17, NIP65 or similar NIPs.
pub const GOSSIP: Self = Self(1 << 3); // 8

/// OUTBOX means automatically added relay that will perform write operations (WRITE of kind 10002).
pub const OUTBOX: Self = Self(1 << 4); // 16

/// DISCOVERY means that relay has role to get relay lists (i.e. events with 10002) of public keys.
pub const DISCOVERY: Self = Self(1 << 5); // 32
/// DISCOVERY means that relay has role to get relay lists (i.e., events with kind `10002`) of public keys.
pub const DISCOVERY: Self = Self(1 << 4); // 16

/// Add service flags together.
#[inline]
Expand Down Expand Up @@ -186,16 +185,10 @@ impl AtomicRelayServiceFlags {
self.has_all(RelayServiceFlags::PING)
}

/// Check if `INBOX` service is enabled
#[inline]
pub fn has_inbox(&self) -> bool {
self.has_all(RelayServiceFlags::INBOX)
}

/// Check if `OUTBOX` service is enabled
/// Check if `GOSSIP` service is enabled
#[inline]
pub fn has_outbox(&self) -> bool {
self.has_all(RelayServiceFlags::OUTBOX)
pub fn has_gossip(&self) -> bool {
self.has_all(RelayServiceFlags::GOSSIP)
}

/// Check if `DISCOVERY` service is enabled
Expand All @@ -204,23 +197,18 @@ impl AtomicRelayServiceFlags {
self.has_all(RelayServiceFlags::DISCOVERY)
}

/// Check if `READ`, `INBOX`, `OUTBOX` or `DISCOVERY` services are enabled
/// Check if `READ`, `GOSSIP` or `DISCOVERY` services are enabled
#[inline]
pub fn can_read(&self) -> bool {
self.has_any(
RelayServiceFlags::READ
| RelayServiceFlags::INBOX
| RelayServiceFlags::OUTBOX
| RelayServiceFlags::DISCOVERY,
RelayServiceFlags::READ | RelayServiceFlags::GOSSIP | RelayServiceFlags::DISCOVERY,
)
}

/// Check if `WRITE`, `INBOX` or `OUTBOX` services are enabled
/// Check if `WRITE` or `GOSSIP` services are enabled
#[inline]
pub fn can_write(&self) -> bool {
self.has_any(
RelayServiceFlags::WRITE | RelayServiceFlags::INBOX | RelayServiceFlags::OUTBOX,
)
self.has_any(RelayServiceFlags::WRITE | RelayServiceFlags::GOSSIP)
}
}

Expand All @@ -245,8 +233,7 @@ mod tests {
assert!(flags.has(RelayServiceFlags::READ, FlagCheck::All));
assert!(flags.has(RelayServiceFlags::WRITE, FlagCheck::All));
assert!(!flags.has(RelayServiceFlags::PING, FlagCheck::All));
assert!(!flags.has(RelayServiceFlags::INBOX, FlagCheck::All));
assert!(!flags.has(RelayServiceFlags::OUTBOX, FlagCheck::All));
assert!(!flags.has(RelayServiceFlags::GOSSIP, FlagCheck::All));
assert!(!flags.has(RelayServiceFlags::DISCOVERY, FlagCheck::All));

// Try to add flag
Expand All @@ -266,7 +253,7 @@ mod tests {
// Try to remove multiple flags
flags.add(RelayServiceFlags::WRITE | RelayServiceFlags::DISCOVERY);
flags.remove(
RelayServiceFlags::WRITE | RelayServiceFlags::OUTBOX | RelayServiceFlags::DISCOVERY,
RelayServiceFlags::WRITE | RelayServiceFlags::GOSSIP | RelayServiceFlags::DISCOVERY,
);
assert!(flags.has(
RelayServiceFlags::PING | RelayServiceFlags::READ,
Expand All @@ -288,20 +275,16 @@ mod tests {
));

// Try to add flag
flags.add(RelayServiceFlags::INBOX);
assert!(flags.has(RelayServiceFlags::INBOX, FlagCheck::All));

// Try to add flag
flags.add(RelayServiceFlags::OUTBOX);
assert!(flags.has(RelayServiceFlags::OUTBOX, FlagCheck::All));
flags.add(RelayServiceFlags::GOSSIP);
assert!(flags.has(RelayServiceFlags::GOSSIP, FlagCheck::All));

// Try to add flag
flags.add(RelayServiceFlags::DISCOVERY);
assert!(flags.has(RelayServiceFlags::DISCOVERY, FlagCheck::All));

let flags = RelayServiceFlags::READ | RelayServiceFlags::INBOX | RelayServiceFlags::PING;
let flags = RelayServiceFlags::READ | RelayServiceFlags::GOSSIP | RelayServiceFlags::PING;
assert!(flags.has(
RelayServiceFlags::READ | RelayServiceFlags::INBOX,
RelayServiceFlags::READ | RelayServiceFlags::GOSSIP,
FlagCheck::All
));
assert!(!flags.has(
Expand All @@ -318,7 +301,7 @@ mod tests {
let f = AtomicRelayServiceFlags::new(RelayServiceFlags::READ | RelayServiceFlags::WRITE);
assert!(f.can_read());

let f = AtomicRelayServiceFlags::new(RelayServiceFlags::INBOX);
let f = AtomicRelayServiceFlags::new(RelayServiceFlags::GOSSIP);
assert!(f.can_read());

let f = AtomicRelayServiceFlags::new(RelayServiceFlags::DISCOVERY);
Expand All @@ -333,7 +316,7 @@ mod tests {
let f = AtomicRelayServiceFlags::new(RelayServiceFlags::READ | RelayServiceFlags::WRITE);
assert!(f.can_write());

let f = AtomicRelayServiceFlags::new(RelayServiceFlags::INBOX);
let f = AtomicRelayServiceFlags::new(RelayServiceFlags::GOSSIP);
assert!(f.can_write());

let f = AtomicRelayServiceFlags::new(RelayServiceFlags::DISCOVERY);
Expand Down
35 changes: 7 additions & 28 deletions crates/nostr-sdk/src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -498,29 +498,15 @@ impl Client {
}

#[inline]
async fn add_inbox_relay<U>(&self, url: U) -> Result<bool, Error>
async fn add_gossip_relay<U>(&self, url: U) -> Result<bool, Error>
where
U: TryIntoUrl,
pool::Error: From<<U as TryIntoUrl>::Err>,
{
self.get_or_add_relay_with_flag(
url,
false,
RelayServiceFlags::PING | RelayServiceFlags::INBOX,
)
.await
}

#[inline]
async fn add_outbox_relay<U>(&self, url: U) -> Result<bool, Error>
where
U: TryIntoUrl,
pool::Error: From<<U as TryIntoUrl>::Err>,
{
self.get_or_add_relay_with_flag(
url,
false,
RelayServiceFlags::PING | RelayServiceFlags::OUTBOX,
RelayServiceFlags::PING | RelayServiceFlags::GOSSIP,
)
.await
}
Expand Down Expand Up @@ -1051,14 +1037,14 @@ impl Client {

// Add outbox relays
for url in outbox.iter() {
if self.add_outbox_relay(url).await? {
if self.add_gossip_relay(url).await? {
self.connect_relay(url).await?;
}
}

// Add inbox relays
for url in inbox.iter() {
if self.add_inbox_relay(url).await? {
if self.add_gossip_relay(url).await? {
self.connect_relay(url).await?;
}
}
Expand Down Expand Up @@ -1778,16 +1764,9 @@ impl Client {
}
}

// Add outbox relays
for url in broken_down.outbox_urls.into_iter() {
if self.add_outbox_relay(&url).await? {
self.connect_relay(url).await?;
}
}

// Add inbox relays
for url in broken_down.inbox_urls.into_iter() {
if self.add_inbox_relay(&url).await? {
// Add outbox and inbox relays
for url in broken_down.urls.into_iter() {
if self.add_gossip_relay(&url).await? {
self.connect_relay(url).await?;
}
}
Expand Down
16 changes: 6 additions & 10 deletions crates/nostr-sdk/src/gossip/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ pub struct BrokenDownFilters {
pub filters: HashMap<Url, Vec<Filter>>,
/// Filters that can be sent to read relays (generic query, not related to public keys)
pub other: Option<Vec<Filter>>,
pub outbox_urls: HashSet<Url>,
pub inbox_urls: HashSet<Url>,
pub urls: HashSet<Url>,
}

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -229,8 +228,7 @@ impl GossipGraph {
pub async fn break_down_filters(&self, filters: Vec<Filter>) -> BrokenDownFilters {
let mut map: HashMap<Url, BTreeSet<Filter>> = HashMap::new();
let mut other = Vec::new();
let mut outbox_urls = HashSet::new();
let mut inbox_urls = HashSet::new();
let mut urls = HashSet::new();

let txn = self.public_keys.read().await;

Expand All @@ -249,7 +247,7 @@ impl GossipGraph {

// Construct new filters
for (relay, pk_set) in outbox.into_iter() {
outbox_urls.insert(relay.clone());
urls.insert(relay.clone());

// Clone filter and change authors
let mut new_filter: Filter = filter.clone();
Expand All @@ -270,7 +268,7 @@ impl GossipGraph {

// Construct new filters
for (relay, pk_set) in inbox.into_iter() {
inbox_urls.insert(relay.clone());
urls.insert(relay.clone());

// Clone filter and change p tags
let mut new_filter: Filter = filter.clone();
Expand All @@ -293,8 +291,7 @@ impl GossipGraph {
let relays = self.get_nip65_relays(&txn, pks, None);

for relay in relays.into_iter() {
outbox_urls.insert(relay.clone());
inbox_urls.insert(relay.clone());
urls.insert(relay.clone());

// Update map
map.entry(relay)
Expand All @@ -318,8 +315,7 @@ impl GossipGraph {
.map(|(u, f)| (u, f.into_iter().collect::<Vec<_>>()))
.collect(),
other: if other.is_empty() { None } else { Some(other) },
outbox_urls,
inbox_urls,
urls,
}
}
}
Expand Down

0 comments on commit a4ebf69

Please sign in to comment.