|
|
|
@ -7,6 +7,7 @@ public extension LokiAPI {
|
|
|
|
|
// MARK: Settings
|
|
|
|
|
private static let minimumSnodeCount = 2
|
|
|
|
|
private static let targetSnodeCount = 3
|
|
|
|
|
private static let maxRandomSnodePoolSize = 1024
|
|
|
|
|
fileprivate static let failureThreshold = 2
|
|
|
|
|
|
|
|
|
|
// MARK: Caching
|
|
|
|
@ -39,7 +40,7 @@ public extension LokiAPI {
|
|
|
|
|
"method" : "get_n_service_nodes",
|
|
|
|
|
"params" : [
|
|
|
|
|
"active_only" : true,
|
|
|
|
|
"limit" : 24,
|
|
|
|
|
"limit" : maxRandomSnodePoolSize,
|
|
|
|
|
"fields" : [
|
|
|
|
|
"public_ip" : true,
|
|
|
|
|
"storage_port" : true,
|
|
|
|
@ -59,6 +60,7 @@ public extension LokiAPI {
|
|
|
|
|
}
|
|
|
|
|
return LokiAPITarget(address: "https://\(address)", port: UInt16(port), publicKeySet: LokiAPITarget.KeySet(idKey: idKey, encryptionKey: encryptionKey))
|
|
|
|
|
})
|
|
|
|
|
// randomElement() uses the system's default random generator, which is cryptographically secure
|
|
|
|
|
return randomSnodePool.randomElement()!
|
|
|
|
|
}.recover(on: DispatchQueue.global()) { error -> Promise<LokiAPITarget> in
|
|
|
|
|
print("[Loki] Failed to contact seed node at: \(target).")
|
|
|
|
@ -66,6 +68,7 @@ public extension LokiAPI {
|
|
|
|
|
}.retryingIfNeeded(maxRetryCount: 16) // The seed nodes have historically been unreliable
|
|
|
|
|
} else {
|
|
|
|
|
return Promise<LokiAPITarget> { seal in
|
|
|
|
|
// randomElement() uses the system's default random generator, which is cryptographically secure
|
|
|
|
|
seal.fulfill(randomSnodePool.randomElement()!)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|