Fix crash when you have invalid relays in your relay list
Changelog-Fixed: Fix crash when you have invalid relays in your relay list
This commit is contained in:
@@ -121,7 +121,6 @@
|
|||||||
4C5F9118283D88E40052CD1C /* FollowingModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C5F9117283D88E40052CD1C /* FollowingModel.swift */; };
|
4C5F9118283D88E40052CD1C /* FollowingModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C5F9117283D88E40052CD1C /* FollowingModel.swift */; };
|
||||||
4C633350283D40E500B1C9C3 /* HomeModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C63334F283D40E500B1C9C3 /* HomeModel.swift */; };
|
4C633350283D40E500B1C9C3 /* HomeModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C63334F283D40E500B1C9C3 /* HomeModel.swift */; };
|
||||||
4C633352283D419F00B1C9C3 /* SignalModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C633351283D419F00B1C9C3 /* SignalModel.swift */; };
|
4C633352283D419F00B1C9C3 /* SignalModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C633351283D419F00B1C9C3 /* SignalModel.swift */; };
|
||||||
4C649844285A952100EAE2B3 /* LocalUserConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C649843285A952100EAE2B3 /* LocalUserConfig.swift */; };
|
|
||||||
4C64987C286D03E000EAE2B3 /* DirectMessagesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C64987B286D03E000EAE2B3 /* DirectMessagesView.swift */; };
|
4C64987C286D03E000EAE2B3 /* DirectMessagesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C64987B286D03E000EAE2B3 /* DirectMessagesView.swift */; };
|
||||||
4C64987E286D082C00EAE2B3 /* DirectMessagesModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C64987D286D082C00EAE2B3 /* DirectMessagesModel.swift */; };
|
4C64987E286D082C00EAE2B3 /* DirectMessagesModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C64987D286D082C00EAE2B3 /* DirectMessagesModel.swift */; };
|
||||||
4C649881286E0EE300EAE2B3 /* secp256k1 in Frameworks */ = {isa = PBXBuildFile; productRef = 4C649880286E0EE300EAE2B3 /* secp256k1 */; };
|
4C649881286E0EE300EAE2B3 /* secp256k1 in Frameworks */ = {isa = PBXBuildFile; productRef = 4C649880286E0EE300EAE2B3 /* secp256k1 */; };
|
||||||
@@ -530,7 +529,6 @@
|
|||||||
4C5F9117283D88E40052CD1C /* FollowingModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowingModel.swift; sourceTree = "<group>"; };
|
4C5F9117283D88E40052CD1C /* FollowingModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowingModel.swift; sourceTree = "<group>"; };
|
||||||
4C63334F283D40E500B1C9C3 /* HomeModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeModel.swift; sourceTree = "<group>"; };
|
4C63334F283D40E500B1C9C3 /* HomeModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeModel.swift; sourceTree = "<group>"; };
|
||||||
4C633351283D419F00B1C9C3 /* SignalModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignalModel.swift; sourceTree = "<group>"; };
|
4C633351283D419F00B1C9C3 /* SignalModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignalModel.swift; sourceTree = "<group>"; };
|
||||||
4C649843285A952100EAE2B3 /* LocalUserConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalUserConfig.swift; sourceTree = "<group>"; };
|
|
||||||
4C64987B286D03E000EAE2B3 /* DirectMessagesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DirectMessagesView.swift; sourceTree = "<group>"; };
|
4C64987B286D03E000EAE2B3 /* DirectMessagesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DirectMessagesView.swift; sourceTree = "<group>"; };
|
||||||
4C64987D286D082C00EAE2B3 /* DirectMessagesModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DirectMessagesModel.swift; sourceTree = "<group>"; };
|
4C64987D286D082C00EAE2B3 /* DirectMessagesModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DirectMessagesModel.swift; sourceTree = "<group>"; };
|
||||||
4C75EFA327FA577B0006080F /* PostView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostView.swift; sourceTree = "<group>"; };
|
4C75EFA327FA577B0006080F /* PostView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostView.swift; sourceTree = "<group>"; };
|
||||||
@@ -837,7 +835,6 @@
|
|||||||
4C5F9117283D88E40052CD1C /* FollowingModel.swift */,
|
4C5F9117283D88E40052CD1C /* FollowingModel.swift */,
|
||||||
4C987B56283FD07F0042CE38 /* FollowersModel.swift */,
|
4C987B56283FD07F0042CE38 /* FollowersModel.swift */,
|
||||||
4C5C7E67284ED36500A22DF5 /* SearchHomeModel.swift */,
|
4C5C7E67284ED36500A22DF5 /* SearchHomeModel.swift */,
|
||||||
4C649843285A952100EAE2B3 /* LocalUserConfig.swift */,
|
|
||||||
4C64987D286D082C00EAE2B3 /* DirectMessagesModel.swift */,
|
4C64987D286D082C00EAE2B3 /* DirectMessagesModel.swift */,
|
||||||
4C216F372871EDE300040376 /* DirectMessageModel.swift */,
|
4C216F372871EDE300040376 /* DirectMessageModel.swift */,
|
||||||
4C99737A28C92A9200E53835 /* ChatroomMetadata.swift */,
|
4C99737A28C92A9200E53835 /* ChatroomMetadata.swift */,
|
||||||
@@ -1572,7 +1569,6 @@
|
|||||||
4C8D00CA29DF80350036AF10 /* TruncatedText.swift in Sources */,
|
4C8D00CA29DF80350036AF10 /* TruncatedText.swift in Sources */,
|
||||||
4C9BB83429C12D9900FC4E37 /* EventProfileName.swift in Sources */,
|
4C9BB83429C12D9900FC4E37 /* EventProfileName.swift in Sources */,
|
||||||
4CB8838F296F781C00DC99E7 /* ReactionsView.swift in Sources */,
|
4CB8838F296F781C00DC99E7 /* ReactionsView.swift in Sources */,
|
||||||
4C649844285A952100EAE2B3 /* LocalUserConfig.swift in Sources */,
|
|
||||||
4C75EFB328049D640006080F /* NostrEvent.swift in Sources */,
|
4C75EFB328049D640006080F /* NostrEvent.swift in Sources */,
|
||||||
4CA2EFA0280E37AC0044ACD8 /* TimelineView.swift in Sources */,
|
4CA2EFA0280E37AC0044ACD8 /* TimelineView.swift in Sources */,
|
||||||
4C30AC7629A5770900E2BD5A /* NotificationItemView.swift in Sources */,
|
4C30AC7629A5770900E2BD5A /* NotificationItemView.swift in Sources */,
|
||||||
|
|||||||
@@ -629,7 +629,7 @@ struct ContentView: View {
|
|||||||
|
|
||||||
let new_relay_filters = load_relay_filters(pubkey) == nil
|
let new_relay_filters = load_relay_filters(pubkey) == nil
|
||||||
for relay in bootstrap_relays {
|
for relay in bootstrap_relays {
|
||||||
if let url = URL(string: relay) {
|
if let url = RelayURL(relay) {
|
||||||
add_new_relay(relay_filters: relay_filters, metadatas: metadatas, pool: pool, url: url, info: .rw, new_relay_filters: new_relay_filters)
|
add_new_relay(relay_filters: relay_filters, metadatas: metadatas, pool: pool, url: url, info: .rw, new_relay_filters: new_relay_filters)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -242,7 +242,7 @@ func follow_with_existing_contacts(our_pubkey: String, our_contacts: NostrEvent,
|
|||||||
|
|
||||||
func make_contact_relays(_ relays: [RelayDescriptor]) -> [String: RelayInfo] {
|
func make_contact_relays(_ relays: [RelayDescriptor]) -> [String: RelayInfo] {
|
||||||
return relays.reduce(into: [:]) { acc, relay in
|
return relays.reduce(into: [:]) { acc, relay in
|
||||||
acc[relay.url.absoluteString] = relay.info
|
acc[relay.url.url.absoluteString] = relay.info
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -809,7 +809,7 @@ func load_our_relays(state: DamusState, m_old_ev: NostrEvent?, ev: NostrEvent) {
|
|||||||
for d in diff {
|
for d in diff {
|
||||||
changed = true
|
changed = true
|
||||||
if new.contains(d) {
|
if new.contains(d) {
|
||||||
if let url = URL(string: d) {
|
if let url = RelayURL(d) {
|
||||||
add_new_relay(relay_filters: state.relay_filters, metadatas: state.relay_metadata, pool: state.pool, url: url, info: decoded[d] ?? .rw, new_relay_filters: new_relay_filters)
|
add_new_relay(relay_filters: state.relay_filters, metadatas: state.relay_metadata, pool: state.pool, url: url, info: decoded[d] ?? .rw, new_relay_filters: new_relay_filters)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -823,10 +823,10 @@ func load_our_relays(state: DamusState, m_old_ev: NostrEvent?, ev: NostrEvent) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func add_new_relay(relay_filters: RelayFilters, metadatas: RelayMetadatas, pool: RelayPool, url: URL, info: RelayInfo, new_relay_filters: Bool) {
|
func add_new_relay(relay_filters: RelayFilters, metadatas: RelayMetadatas, pool: RelayPool, url: RelayURL, info: RelayInfo, new_relay_filters: Bool) {
|
||||||
try? pool.add_relay(url, info: info)
|
try? pool.add_relay(url, info: info)
|
||||||
|
|
||||||
let relay_id = url.absoluteString
|
let relay_id = url.id
|
||||||
guard metadatas.lookup(relay_id: relay_id) == nil else {
|
guard metadatas.lookup(relay_id: relay_id) == nil else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
//
|
|
||||||
// LocalUserConfig.swift
|
|
||||||
// damus
|
|
||||||
//
|
|
||||||
// Created by William Casarin on 2022-06-15.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
|
|
||||||
struct LocalUserConfig: Codable {
|
|
||||||
let relays: [RelayDescriptor]
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -694,7 +694,7 @@ func generate_private_keypair(our_privkey: String, id: String, created_at: Int64
|
|||||||
func make_zap_request_event(keypair: FullKeypair, content: String, relays: [RelayDescriptor], target: ZapTarget, zap_type: ZapType) -> NostrEvent? {
|
func make_zap_request_event(keypair: FullKeypair, content: String, relays: [RelayDescriptor], target: ZapTarget, zap_type: ZapType) -> NostrEvent? {
|
||||||
var tags = zap_target_to_tags(target)
|
var tags = zap_target_to_tags(target)
|
||||||
var relay_tag = ["relays"]
|
var relay_tag = ["relays"]
|
||||||
relay_tag.append(contentsOf: relays.map { $0.url.absoluteString })
|
relay_tag.append(contentsOf: relays.map { $0.url.id })
|
||||||
tags.append(relay_tag)
|
tags.append(relay_tag)
|
||||||
|
|
||||||
var kp = keypair
|
var kp = keypair
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ public struct RelayInfo: Codable {
|
|||||||
static let rw = RelayInfo(read: true, write: true)
|
static let rw = RelayInfo(read: true, write: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct RelayDescriptor: Codable {
|
public struct RelayDescriptor {
|
||||||
public let url: URL
|
public let url: RelayURL
|
||||||
public let info: RelayInfo
|
public let info: RelayInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,6 +79,6 @@ enum RelayError: Error {
|
|||||||
case RelayNotFound
|
case RelayNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
func get_relay_id(_ url: URL) -> String {
|
func get_relay_id(_ url: RelayURL) -> String {
|
||||||
return url.absoluteString
|
return url.url.absoluteString
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,18 +13,42 @@ enum NostrConnectionEvent {
|
|||||||
case nostr_event(NostrResponse)
|
case nostr_event(NostrResponse)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public struct RelayURL: Hashable {
|
||||||
|
private(set) var url: URL
|
||||||
|
|
||||||
|
var id: String {
|
||||||
|
return url.absoluteString
|
||||||
|
}
|
||||||
|
|
||||||
|
init?(_ str: String) {
|
||||||
|
guard let url = URL(string: str) else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let scheme = url.scheme else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
guard scheme == "ws" || scheme == "wss" else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
self.url = url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
final class RelayConnection {
|
final class RelayConnection {
|
||||||
private(set) var isConnected = false
|
private(set) var isConnected = false
|
||||||
private(set) var isConnecting = false
|
private(set) var isConnecting = false
|
||||||
|
|
||||||
private(set) var last_connection_attempt: TimeInterval = 0
|
private(set) var last_connection_attempt: TimeInterval = 0
|
||||||
private lazy var socket = WebSocket(url)
|
private lazy var socket = WebSocket(url.url)
|
||||||
private var subscriptionToken: AnyCancellable?
|
private var subscriptionToken: AnyCancellable?
|
||||||
|
|
||||||
private var handleEvent: (NostrConnectionEvent) -> ()
|
private var handleEvent: (NostrConnectionEvent) -> ()
|
||||||
private let url: URL
|
private let url: RelayURL
|
||||||
|
|
||||||
init(url: URL, handleEvent: @escaping (NostrConnectionEvent) -> ()) {
|
init(url: RelayURL, handleEvent: @escaping (NostrConnectionEvent) -> ()) {
|
||||||
self.url = url
|
self.url = url
|
||||||
self.handleEvent = handleEvent
|
self.handleEvent = handleEvent
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ class RelayPool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func add_relay(_ url: URL, info: RelayInfo) throws {
|
func add_relay(_ url: RelayURL, info: RelayInfo) throws {
|
||||||
let relay_id = get_relay_id(url)
|
let relay_id = get_relay_id(url)
|
||||||
if get_relay(relay_id) != nil {
|
if get_relay(relay_id) != nil {
|
||||||
throw RelayError.RelayAlreadyExists
|
throw RelayError.RelayAlreadyExists
|
||||||
@@ -127,7 +127,7 @@ class RelayPool {
|
|||||||
let is_connecting = c.isConnecting
|
let is_connecting = c.isConnecting
|
||||||
|
|
||||||
if is_connecting && (Date.now.timeIntervalSince1970 - c.last_connection_attempt) > 5 {
|
if is_connecting && (Date.now.timeIntervalSince1970 - c.last_connection_attempt) > 5 {
|
||||||
print("stale connection detected (\(relay.descriptor.url.absoluteString)). retrying...")
|
print("stale connection detected (\(relay.descriptor.url.url.absoluteString)). retrying...")
|
||||||
relay.connection.reconnect()
|
relay.connection.reconnect()
|
||||||
} else if relay.is_broken || is_connecting || c.isConnected {
|
} else if relay.is_broken || is_connecting || c.isConnected {
|
||||||
continue
|
continue
|
||||||
@@ -271,8 +271,10 @@ class RelayPool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func add_rw_relay(_ pool: RelayPool, _ url: String) {
|
func add_rw_relay(_ pool: RelayPool, _ url: String) {
|
||||||
let url_ = URL(string: url)!
|
guard let url = RelayURL(url) else {
|
||||||
try? pool.add_relay(url_, info: RelayInfo.rw)
|
return
|
||||||
|
}
|
||||||
|
try? pool.add_relay(url, info: RelayInfo.rw)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -109,9 +109,7 @@ class PostBox {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let remaining = pool.descriptors.map {
|
let remaining = pool.descriptors.map { $0.url.id }
|
||||||
$0.url.absoluteString
|
|
||||||
}
|
|
||||||
|
|
||||||
let posted_ev = PostedEvent(event: event, remaining: remaining)
|
let posted_ev = PostedEvent(event: event, remaining: remaining)
|
||||||
events[event.id] = posted_ev
|
events[event.id] = posted_ev
|
||||||
|
|||||||
@@ -89,6 +89,6 @@ func load_relay_filters(_ pubkey: String) -> Set<RelayFilter>? {
|
|||||||
|
|
||||||
func determine_to_relays(pool: RelayPool, filters: RelayFilters) -> [String] {
|
func determine_to_relays(pool: RelayPool, filters: RelayFilters) -> [String] {
|
||||||
return pool.descriptors
|
return pool.descriptors
|
||||||
.map { $0.url.absoluteString }
|
.map { $0.url.url.absoluteString }
|
||||||
.filter { !filters.is_filtered(timeline: .search, relay_id: $0) }
|
.filter { !filters.is_filtered(timeline: .search, relay_id: $0) }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ struct RelayFilterView: View {
|
|||||||
.padding(.top, 20)
|
.padding(.top, 20)
|
||||||
.padding(.bottom, 0)
|
.padding(.bottom, 0)
|
||||||
|
|
||||||
List(Array(relays), id: \.url) { relay in
|
List(Array(relays), id: \.url.id) { relay in
|
||||||
RelayToggle(state: state, timeline: timeline, relay_id: relay.url.absoluteString)
|
RelayToggle(state: state, timeline: timeline, relay_id: relay.url.url.absoluteString)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ struct RelayConfigView: View {
|
|||||||
var recommended: [RelayDescriptor] {
|
var recommended: [RelayDescriptor] {
|
||||||
let rs: [RelayDescriptor] = []
|
let rs: [RelayDescriptor] = []
|
||||||
return BOOTSTRAP_RELAYS.reduce(into: rs) { xs, x in
|
return BOOTSTRAP_RELAYS.reduce(into: rs) { xs, x in
|
||||||
if state.pool.get_relay(x) == nil, let url = URL(string: x) {
|
if state.pool.get_relay(x) == nil, let url = RelayURL(x) {
|
||||||
xs.append(RelayDescriptor(url: url, info: .rw))
|
xs.append(RelayDescriptor(url: url, info: .rw))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -75,7 +75,7 @@ struct RelayConfigView: View {
|
|||||||
new_relay.removeLast();
|
new_relay.removeLast();
|
||||||
}
|
}
|
||||||
|
|
||||||
guard let url = URL(string: new_relay) else {
|
guard let url = RelayURL(new_relay) else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,7 +120,7 @@ struct RelayConfigView: View {
|
|||||||
|
|
||||||
Section {
|
Section {
|
||||||
List(Array(relays), id: \.url) { relay in
|
List(Array(relays), id: \.url) { relay in
|
||||||
RelayView(state: state, relay: relay.url.absoluteString, showActionButtons: $showActionButtons)
|
RelayView(state: state, relay: relay.url.id, showActionButtons: $showActionButtons)
|
||||||
}
|
}
|
||||||
} header: {
|
} header: {
|
||||||
HStack {
|
HStack {
|
||||||
@@ -133,7 +133,7 @@ struct RelayConfigView: View {
|
|||||||
if recommended.count > 0 {
|
if recommended.count > 0 {
|
||||||
Section {
|
Section {
|
||||||
List(recommended, id: \.url) { r in
|
List(recommended, id: \.url) { r in
|
||||||
RecommendedRelayView(damus: state, relay: r.url.absoluteString, showActionButtons: $showActionButtons)
|
RecommendedRelayView(damus: state, relay: r.url.id, showActionButtons: $showActionButtons)
|
||||||
}
|
}
|
||||||
} header: {
|
} header: {
|
||||||
Text(NSLocalizedString("Recommended Relays", comment: "Section title for recommend relay servers that could be added as part of configuration"))
|
Text(NSLocalizedString("Recommended Relays", comment: "Section title for recommend relay servers that could be added as part of configuration"))
|
||||||
|
|||||||
Reference in New Issue
Block a user