relays: keep in sync with user relay list
Still need to figure out how to ensure new bootstrap relays are added... Changelog-Changed: Ensure contact relay list is kept in sync with internal relay pool
This commit is contained in:
@@ -15,6 +15,7 @@ var BOOTSTRAP_RELAYS = [
|
|||||||
"wss://nostr.fmt.wiz.biz",
|
"wss://nostr.fmt.wiz.biz",
|
||||||
"wss://relay.nostr.bg",
|
"wss://relay.nostr.bg",
|
||||||
"wss://nostr.oxtr.dev",
|
"wss://nostr.oxtr.dev",
|
||||||
|
"wss://nostr.v0l.io",
|
||||||
]
|
]
|
||||||
|
|
||||||
struct TimestampedProfile {
|
struct TimestampedProfile {
|
||||||
|
|||||||
@@ -139,13 +139,8 @@ func decode_json_relays(_ content: String) -> [String: RelayInfo]? {
|
|||||||
return decode_json(content)
|
return decode_json(content)
|
||||||
}
|
}
|
||||||
|
|
||||||
func remove_relay(ev: NostrEvent, privkey: String, relay: String) -> NostrEvent? {
|
func remove_relay(ev: NostrEvent, current_relays: [RelayDescriptor], privkey: String, relay: String) -> NostrEvent? {
|
||||||
let damus_relay = RelayDescriptor(url: URL(string: "wss://relay.damus.io")!, info: .rw)
|
var relays = ensure_relay_info(relays: current_relays, content: ev.content)
|
||||||
|
|
||||||
var relays = ensure_relay_info(relays: [damus_relay], content: ev.content)
|
|
||||||
guard relays.index(forKey: relay) != nil else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
relays.removeValue(forKey: relay)
|
relays.removeValue(forKey: relay)
|
||||||
|
|
||||||
|
|||||||
@@ -446,21 +446,7 @@ func add_contact_if_friend(contacts: Contacts, ev: NostrEvent) {
|
|||||||
contacts.add_friend_contact(ev)
|
contacts.add_friend_contact(ev)
|
||||||
}
|
}
|
||||||
|
|
||||||
func load_our_contacts(contacts: Contacts, our_pubkey: String, ev: NostrEvent) {
|
func load_our_contacts(contacts: Contacts, our_pubkey: String, m_old_ev: NostrEvent?, ev: NostrEvent) {
|
||||||
guard ev.pubkey == our_pubkey else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// only use new stuff
|
|
||||||
if let current_ev = contacts.event {
|
|
||||||
guard ev.created_at > current_ev.created_at else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let m_old_ev = contacts.event
|
|
||||||
contacts.event = ev
|
|
||||||
|
|
||||||
var new_pks = Set<String>()
|
var new_pks = Set<String>()
|
||||||
// our contacts
|
// our contacts
|
||||||
for tag in ev.tags {
|
for tag in ev.tags {
|
||||||
@@ -572,35 +558,68 @@ func robohash(_ pk: String) -> String {
|
|||||||
return "https://robohash.org/" + pk
|
return "https://robohash.org/" + pk
|
||||||
}
|
}
|
||||||
|
|
||||||
func process_contact_event(pool: RelayPool, contacts: Contacts, pubkey: String, ev: NostrEvent) {
|
func load_our_stuff(pool: RelayPool, contacts: Contacts, pubkey: String, ev: NostrEvent) {
|
||||||
load_our_contacts(contacts: contacts, our_pubkey: pubkey, ev: ev)
|
guard ev.pubkey == pubkey else {
|
||||||
load_our_relays(contacts: contacts, our_pubkey: pubkey, pool: pool, ev: ev)
|
|
||||||
add_contact_if_friend(contacts: contacts, ev: ev)
|
|
||||||
}
|
|
||||||
|
|
||||||
func load_our_relays(contacts: Contacts, our_pubkey: String, pool: RelayPool, ev: NostrEvent) {
|
|
||||||
guard ev.pubkey == our_pubkey else {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// only load new stuff
|
// only use new stuff
|
||||||
if let old_contacts = contacts.event {
|
if let current_ev = contacts.event {
|
||||||
guard ev.created_at > old_contacts.created_at else {
|
guard ev.created_at > current_ev.created_at else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let m_old_ev = contacts.event
|
||||||
|
contacts.event = ev
|
||||||
|
|
||||||
|
load_our_contacts(contacts: contacts, our_pubkey: pubkey, m_old_ev: m_old_ev, ev: ev)
|
||||||
|
load_our_relays(contacts: contacts, our_pubkey: pubkey, pool: pool, m_old_ev: m_old_ev, ev: ev)
|
||||||
|
}
|
||||||
|
|
||||||
|
func process_contact_event(pool: RelayPool, contacts: Contacts, pubkey: String, ev: NostrEvent) {
|
||||||
|
load_our_stuff(pool: pool, contacts: contacts, pubkey: pubkey, ev: ev)
|
||||||
|
add_contact_if_friend(contacts: contacts, ev: ev)
|
||||||
|
}
|
||||||
|
|
||||||
|
func load_our_relays(contacts: Contacts, our_pubkey: String, pool: RelayPool, m_old_ev: NostrEvent?, ev: NostrEvent) {
|
||||||
|
let bootstrap_dict: [String: RelayInfo] = [:]
|
||||||
|
let old_decoded = m_old_ev.flatMap { decode_json_relays($0.content) } ?? BOOTSTRAP_RELAYS.reduce(into: bootstrap_dict) { (d, r) in
|
||||||
|
d[r] = .rw
|
||||||
|
}
|
||||||
|
|
||||||
guard let decoded = decode_json_relays(ev.content) else {
|
guard let decoded = decode_json_relays(ev.content) else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var changed = false
|
||||||
|
|
||||||
|
var new = Set<String>()
|
||||||
for key in decoded.keys {
|
for key in decoded.keys {
|
||||||
if let url = URL(string: key) {
|
new.insert(key)
|
||||||
if let _ = try? pool.add_relay(url, info: decoded[key]!) {
|
}
|
||||||
pool.connect(to: [key])
|
|
||||||
|
var old = Set<String>()
|
||||||
|
for key in old_decoded.keys {
|
||||||
|
old.insert(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
let diff = old.symmetricDifference(new)
|
||||||
|
|
||||||
|
for d in diff {
|
||||||
|
changed = true
|
||||||
|
if new.contains(d) {
|
||||||
|
if let url = URL(string: d) {
|
||||||
|
try? pool.add_relay(url, info: decoded[d] ?? .rw)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
pool.remove_relay(d)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if changed {
|
||||||
|
notify(.relays_changed, ())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -28,12 +28,14 @@ class Relay: Identifiable {
|
|||||||
let descriptor: RelayDescriptor
|
let descriptor: RelayDescriptor
|
||||||
let connection: RelayConnection
|
let connection: RelayConnection
|
||||||
|
|
||||||
|
var last_pong: UInt32
|
||||||
var flags: Int
|
var flags: Int
|
||||||
|
|
||||||
init(descriptor: RelayDescriptor, connection: RelayConnection) {
|
init(descriptor: RelayDescriptor, connection: RelayConnection) {
|
||||||
self.flags = 0
|
self.flags = 0
|
||||||
self.descriptor = descriptor
|
self.descriptor = descriptor
|
||||||
self.connection = connection
|
self.connection = connection
|
||||||
|
self.last_pong = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func mark_broken() {
|
func mark_broken() {
|
||||||
|
|||||||
@@ -179,8 +179,23 @@ class RelayPool {
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func record_last_pong(relay_id: String, event: NostrConnectionEvent) {
|
||||||
|
if case .ws_event(let ws_event) = event {
|
||||||
|
if case .pong = ws_event {
|
||||||
|
for relay in relays {
|
||||||
|
if relay.id == relay_id {
|
||||||
|
relay.last_pong = UInt32(Date.now.timeIntervalSince1970)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func handle_event(relay_id: String, event: NostrConnectionEvent) {
|
func handle_event(relay_id: String, event: NostrConnectionEvent) {
|
||||||
|
record_last_pong(relay_id: relay_id, event: event)
|
||||||
|
|
||||||
// handle reconnect logic, etc?
|
// handle reconnect logic, etc?
|
||||||
for handler in handlers {
|
for handler in handlers {
|
||||||
handler.callback(relay_id, event)
|
handler.callback(relay_id, event)
|
||||||
@@ -193,3 +208,4 @@ func add_rw_relay(_ pool: RelayPool, _ url: String) {
|
|||||||
try? pool.add_relay(url_, info: RelayInfo.rw)
|
try? pool.add_relay(url_, info: RelayInfo.rw)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,12 @@ extension Notification.Name {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension Notification.Name {
|
||||||
|
static var relays_changed: Notification.Name {
|
||||||
|
return Notification.Name("relays_changed")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extension Notification.Name {
|
extension Notification.Name {
|
||||||
static var select_event: Notification.Name {
|
static var select_event: Notification.Name {
|
||||||
return Notification.Name("select_event")
|
return Notification.Name("select_event")
|
||||||
|
|||||||
@@ -41,13 +41,9 @@ struct ConfigView: View {
|
|||||||
var body: some View {
|
var body: some View {
|
||||||
ZStack(alignment: .leading) {
|
ZStack(alignment: .leading) {
|
||||||
Form {
|
Form {
|
||||||
if let ev = state.contacts.event {
|
Section("Relays") {
|
||||||
Section("Relays") {
|
List(Array(state.pool.relays), id: \.descriptor.url) { relay in
|
||||||
if let relays = decode_json_relays(ev.content) {
|
RelayView(state: state, relay: relay.descriptor.url.absoluteString)
|
||||||
List(Array(relays.keys.sorted()), id: \.self) { relay in
|
|
||||||
RelayView(state: state, ev: ev, relay: relay)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,7 +109,6 @@ struct ConfigView: View {
|
|||||||
}
|
}
|
||||||
.sheet(isPresented: $show_add_relay) {
|
.sheet(isPresented: $show_add_relay) {
|
||||||
AddRelayView(show_add_relay: $show_add_relay, relay: $new_relay) { m_relay in
|
AddRelayView(show_add_relay: $show_add_relay, relay: $new_relay) { m_relay in
|
||||||
|
|
||||||
guard let relay = m_relay else {
|
guard let relay = m_relay else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import SwiftUI
|
|||||||
|
|
||||||
struct RelayView: View {
|
struct RelayView: View {
|
||||||
let state: DamusState
|
let state: DamusState
|
||||||
let ev: NostrEvent
|
|
||||||
let relay: String
|
let relay: String
|
||||||
|
|
||||||
let timer = Timer.publish(every: 2, on: .main, in: .common).autoconnect()
|
let timer = Timer.publish(every: 2, on: .main, in: .common).autoconnect()
|
||||||
@@ -46,7 +45,12 @@ struct RelayView: View {
|
|||||||
.swipeActions {
|
.swipeActions {
|
||||||
if let privkey = state.keypair.privkey {
|
if let privkey = state.keypair.privkey {
|
||||||
Button {
|
Button {
|
||||||
guard let new_ev = remove_relay( ev: ev, privkey: privkey, relay: relay) else {
|
guard let ev = state.contacts.event else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let descriptors = state.pool.descriptors
|
||||||
|
guard let new_ev = remove_relay( ev: ev, current_relays: descriptors, privkey: privkey, relay: relay) else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,6 +68,6 @@ struct RelayView: View {
|
|||||||
|
|
||||||
struct RelayView_Previews: PreviewProvider {
|
struct RelayView_Previews: PreviewProvider {
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
RelayView(state: test_damus_state(), ev: NostrEvent(content: "content", pubkey: "pk"), relay: "wss://relay.damus.io", conn_color: .red)
|
RelayView(state: test_damus_state(), relay: "wss://relay.damus.io", conn_color: .red)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user