Get around CCP bootstrap relay banning by caching user's relays as their bootstrap relays

Changelog-Fixed: Get around CCP bootstrap relay banning by caching user's relays as their bootstrap relays
This commit is contained in:
William Casarin
2023-04-04 10:12:29 -07:00
parent 3da12e708f
commit 679779ab3e
9 changed files with 73 additions and 17 deletions

View File

@@ -164,6 +164,7 @@
4CB9D4A72992D02B00A9A7E4 /* ProfileNameView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CB9D4A62992D02B00A9A7E4 /* ProfileNameView.swift */; }; 4CB9D4A72992D02B00A9A7E4 /* ProfileNameView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CB9D4A62992D02B00A9A7E4 /* ProfileNameView.swift */; };
4CB9D4A92992D2F400A9A7E4 /* FollowsYou.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CB9D4A82992D2F400A9A7E4 /* FollowsYou.swift */; }; 4CB9D4A92992D2F400A9A7E4 /* FollowsYou.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CB9D4A82992D2F400A9A7E4 /* FollowsYou.swift */; };
4CBCA930297DB57F00EC6B2F /* WebsiteLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CBCA92F297DB57F00EC6B2F /* WebsiteLink.swift */; }; 4CBCA930297DB57F00EC6B2F /* WebsiteLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CBCA92F297DB57F00EC6B2F /* WebsiteLink.swift */; };
4CC6193A29DC777C006A86D1 /* RelayBootstrap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CC6193929DC777C006A86D1 /* RelayBootstrap.swift */; };
4CC7AAE7297EFA7B00430951 /* Zap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CC7AAE6297EFA7B00430951 /* Zap.swift */; }; 4CC7AAE7297EFA7B00430951 /* Zap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CC7AAE6297EFA7B00430951 /* Zap.swift */; };
4CC7AAEB297F0AEC00430951 /* BuilderEventView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CC7AAEA297F0AEC00430951 /* BuilderEventView.swift */; }; 4CC7AAEB297F0AEC00430951 /* BuilderEventView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CC7AAEA297F0AEC00430951 /* BuilderEventView.swift */; };
4CC7AAED297F0B9E00430951 /* Highlight.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CC7AAEC297F0B9E00430951 /* Highlight.swift */; }; 4CC7AAED297F0B9E00430951 /* Highlight.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CC7AAEC297F0B9E00430951 /* Highlight.swift */; };
@@ -555,6 +556,7 @@
4CB9D4A62992D02B00A9A7E4 /* ProfileNameView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileNameView.swift; sourceTree = "<group>"; }; 4CB9D4A62992D02B00A9A7E4 /* ProfileNameView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileNameView.swift; sourceTree = "<group>"; };
4CB9D4A82992D2F400A9A7E4 /* FollowsYou.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowsYou.swift; sourceTree = "<group>"; }; 4CB9D4A82992D2F400A9A7E4 /* FollowsYou.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowsYou.swift; sourceTree = "<group>"; };
4CBCA92F297DB57F00EC6B2F /* WebsiteLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebsiteLink.swift; sourceTree = "<group>"; }; 4CBCA92F297DB57F00EC6B2F /* WebsiteLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebsiteLink.swift; sourceTree = "<group>"; };
4CC6193929DC777C006A86D1 /* RelayBootstrap.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelayBootstrap.swift; sourceTree = "<group>"; };
4CC7AAE6297EFA7B00430951 /* Zap.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Zap.swift; sourceTree = "<group>"; }; 4CC7AAE6297EFA7B00430951 /* Zap.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Zap.swift; sourceTree = "<group>"; };
4CC7AAEA297F0AEC00430951 /* BuilderEventView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BuilderEventView.swift; sourceTree = "<group>"; }; 4CC7AAEA297F0AEC00430951 /* BuilderEventView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BuilderEventView.swift; sourceTree = "<group>"; };
4CC7AAEC297F0B9E00430951 /* Highlight.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Highlight.swift; sourceTree = "<group>"; }; 4CC7AAEC297F0B9E00430951 /* Highlight.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Highlight.swift; sourceTree = "<group>"; };
@@ -1164,6 +1166,7 @@
children = ( children = (
4CE8794729941DA700F758CC /* RelayFilters.swift */, 4CE8794729941DA700F758CC /* RelayFilters.swift */,
4CE8794B2995B59E00F758CC /* RelayMetadatas.swift */, 4CE8794B2995B59E00F758CC /* RelayMetadatas.swift */,
4CC6193929DC777C006A86D1 /* RelayBootstrap.swift */,
); );
path = Relays; path = Relays;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -1451,6 +1454,7 @@
4CB55EF5295E679D007FD187 /* UserRelaysView.swift in Sources */, 4CB55EF5295E679D007FD187 /* UserRelaysView.swift in Sources */,
4C363AA228296A7E006E126D /* SearchView.swift in Sources */, 4C363AA228296A7E006E126D /* SearchView.swift in Sources */,
4CC7AAED297F0B9E00430951 /* Highlight.swift in Sources */, 4CC7AAED297F0B9E00430951 /* Highlight.swift in Sources */,
4CC6193A29DC777C006A86D1 /* RelayBootstrap.swift in Sources */,
4C285C8A2838B985008A31F1 /* ProfilePictureSelector.swift in Sources */, 4C285C8A2838B985008A31F1 /* ProfilePictureSelector.swift in Sources */,
4C9F18E429ABDE6D008C55EC /* MaybeAnonPfpView.swift in Sources */, 4C9F18E429ABDE6D008C55EC /* MaybeAnonPfpView.swift in Sources */,
4C75EFB92804A2740006080F /* EventView.swift in Sources */, 4C75EFB92804A2740006080F /* EventView.swift in Sources */,

View File

@@ -8,13 +8,6 @@
import SwiftUI import SwiftUI
import Starscream import Starscream
var BOOTSTRAP_RELAYS = [
"wss://relay.damus.io",
"wss://eden.nostr.land",
"wss://nostr.wine",
"wss://nos.lol",
]
struct TimestampedProfile { struct TimestampedProfile {
let profile: Profile let profile: Profile
let timestamp: Int64 let timestamp: Int64
@@ -605,9 +598,10 @@ struct ContentView: View {
let pool = RelayPool() let pool = RelayPool()
let metadatas = RelayMetadatas() let metadatas = RelayMetadatas()
let relay_filters = RelayFilters(our_pubkey: pubkey) let relay_filters = RelayFilters(our_pubkey: pubkey)
let bootstrap_relays = load_bootstrap_relays(pubkey: pubkey)
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 = URL(string: 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)
} }
@@ -632,7 +626,8 @@ struct ContentView: View {
drafts: Drafts(), drafts: Drafts(),
events: EventCache(), events: EventCache(),
bookmarks: BookmarksManager(pubkey: pubkey), bookmarks: BookmarksManager(pubkey: pubkey),
postbox: PostBox(pool: pool) postbox: PostBox(pool: pool),
bootstrap_relays: bootstrap_relays
) )
home.damus_state = self.damus_state! home.damus_state = self.damus_state!

View File

@@ -28,6 +28,8 @@ struct DamusState {
let bookmarks: BookmarksManager let bookmarks: BookmarksManager
let postbox: PostBox let postbox: PostBox
let bootstrap_relays: [String]
var pubkey: String { var pubkey: String {
return keypair.pubkey return keypair.pubkey
} }
@@ -37,6 +39,6 @@ struct DamusState {
} }
static var empty: DamusState { static var empty: DamusState {
return DamusState.init(pool: RelayPool(), keypair: Keypair(pubkey: "", privkey: ""), likes: EventCounter(our_pubkey: ""), boosts: EventCounter(our_pubkey: ""), contacts: Contacts(our_pubkey: ""), tips: TipCounter(our_pubkey: ""), profiles: Profiles(), dms: DirectMessagesModel(our_pubkey: ""), previews: PreviewCache(), zaps: Zaps(our_pubkey: ""), lnurls: LNUrls(), settings: UserSettingsStore(), relay_filters: RelayFilters(our_pubkey: ""), relay_metadata: RelayMetadatas(), drafts: Drafts(), events: EventCache(), bookmarks: BookmarksManager(pubkey: ""), postbox: PostBox(pool: RelayPool())) return DamusState.init(pool: RelayPool(), keypair: Keypair(pubkey: "", privkey: ""), likes: EventCounter(our_pubkey: ""), boosts: EventCounter(our_pubkey: ""), contacts: Contacts(our_pubkey: ""), tips: TipCounter(our_pubkey: ""), profiles: Profiles(), dms: DirectMessagesModel(our_pubkey: ""), previews: PreviewCache(), zaps: Zaps(our_pubkey: ""), lnurls: LNUrls(), settings: UserSettingsStore(), relay_filters: RelayFilters(our_pubkey: ""), relay_metadata: RelayMetadatas(), drafts: Drafts(), events: EventCache(), bookmarks: BookmarksManager(pubkey: ""), postbox: PostBox(pool: RelayPool()), bootstrap_relays: [])
} }
} }

View File

@@ -743,7 +743,7 @@ func process_contact_event(state: DamusState, ev: NostrEvent) {
func load_our_relays(state: DamusState, m_old_ev: NostrEvent?, ev: NostrEvent) { func load_our_relays(state: DamusState, m_old_ev: NostrEvent?, ev: NostrEvent) {
let bootstrap_dict: [String: RelayInfo] = [:] 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 let old_decoded = m_old_ev.flatMap { decode_json_relays($0.content) } ?? state.bootstrap_relays.reduce(into: bootstrap_dict) { (d, r) in
d[r] = .rw d[r] = .rw
} }
@@ -778,6 +778,7 @@ func load_our_relays(state: DamusState, m_old_ev: NostrEvent?, ev: NostrEvent) {
} }
if changed { if changed {
save_bootstrap_relays(pubkey: state.pubkey, relays: Array(new))
notify(.relays_changed, ()) notify(.relays_changed, ())
} }
} }

View File

@@ -538,16 +538,21 @@ func make_first_contact_event(keypair: Keypair) -> NostrEvent? {
guard let privkey = keypair.privkey else { guard let privkey = keypair.privkey else {
return nil return nil
} }
let bootstrap_relays = load_bootstrap_relays(pubkey: keypair.pubkey)
let rw_relay_info = RelayInfo(read: true, write: true) let rw_relay_info = RelayInfo(read: true, write: true)
var relays: [String: RelayInfo] = [:] var relays: [String: RelayInfo] = [:]
for relay in BOOTSTRAP_RELAYS {
for relay in bootstrap_relays {
relays[relay] = rw_relay_info relays[relay] = rw_relay_info
} }
let relay_json = encode_json(relays)! let relay_json = encode_json(relays)!
let damus_pubkey = "3efdaebb1d8923ebd99c9e7ace3b4194ab45512e2be79c1b7d68d9243e0d2681" let damus_pubkey = "3efdaebb1d8923ebd99c9e7ace3b4194ab45512e2be79c1b7d68d9243e0d2681"
let jb55_pubkey = "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245" // lol
let tags = [ let tags = [
["p", damus_pubkey], ["p", damus_pubkey],
["p", jb55_pubkey],
["p", keypair.pubkey] // you're a friend of yourself! ["p", keypair.pubkey] // you're a friend of yourself!
] ]
let ev = NostrEvent(content: relay_json, let ev = NostrEvent(content: relay_json,

View File

@@ -0,0 +1,44 @@
//
// RelayBootstrap.swift
// damus
//
// Created by William Casarin on 2023-04-04.
//
import Foundation
fileprivate let BOOTSTRAP_RELAYS = [
"wss://relay.damus.io",
"wss://eden.nostr.land",
"wss://nostr.wine",
"wss://nos.lol",
]
func bootstrap_relays_setting_key(pubkey: String) -> String {
return pk_setting_key(pubkey, key: "bootstrap_relays")
}
func save_bootstrap_relays(pubkey: String, relays: [String]) {
let key = bootstrap_relays_setting_key(pubkey: pubkey)
UserDefaults.standard.set(relays, forKey: key)
}
func load_bootstrap_relays(pubkey: String) -> [String] {
let key = bootstrap_relays_setting_key(pubkey: pubkey)
guard let relays = UserDefaults.standard.stringArray(forKey: key) else {
print("loading default bootstrap relays")
return BOOTSTRAP_RELAYS.map { $0 }
}
if relays.count == 0 {
print("loading default bootstrap relays")
return BOOTSTRAP_RELAYS.map { $0 }
}
let loaded_relays = Array(Set(relays + BOOTSTRAP_RELAYS))
print("Loading custom bootstrap relays: \(loaded_relays)")
return loaded_relays
}

View File

@@ -79,11 +79,15 @@ struct LoginView: View {
return return
} }
// this is a weird way to login anyways
/*
var bootstrap_relays = load_bootstrap_relays(pubkey: nip05.pubkey)
for relay in nip05.relays { for relay in nip05.relays {
if !(BOOTSTRAP_RELAYS.contains { $0 == relay }) { if !(bootstrap_relays.contains { $0 == relay }) {
BOOTSTRAP_RELAYS.append(relay) bootstrap_relays.append(relay)
} }
} }
*/
save_pubkey(pubkey: nip05.pubkey) save_pubkey(pubkey: nip05.pubkey)
notify(.login, ()) notify(.login, ())

View File

@@ -22,7 +22,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 state.bootstrap_relays.reduce(into: rs) { xs, x in
if state.pool.get_relay(x) == nil { if state.pool.get_relay(x) == nil {
xs.append(RelayDescriptor(url: URL(string: x)!, info: .rw)) xs.append(RelayDescriptor(url: URL(string: x)!, info: .rw))
} }

View File

@@ -90,7 +90,8 @@ struct SaveKeysView: View {
} }
func complete_account_creation(_ account: CreateAccountModel) { func complete_account_creation(_ account: CreateAccountModel) {
for relay in BOOTSTRAP_RELAYS { let bootstrap_relays = load_bootstrap_relays(pubkey: account.pubkey)
for relay in bootstrap_relays {
add_rw_relay(self.pool, relay) add_rw_relay(self.pool, relay)
} }