mirror of
https://github.com/oxen-io/session-android.git
synced 2025-03-26 01:30:50 +00:00
Clean
This commit is contained in:
parent
7415c728eb
commit
bc66c45bca
@ -32,16 +32,13 @@ import androidx.multidex.MultiDexApplication;
|
||||
import org.conscrypt.Conscrypt;
|
||||
import org.session.libsession.messaging.MessagingConfiguration;
|
||||
import org.session.libsession.messaging.avatars.AvatarHelper;
|
||||
import org.session.libsession.messaging.fileserver.FileServerAPI;
|
||||
import org.session.libsession.messaging.jobs.JobQueue;
|
||||
import org.session.libsession.messaging.opengroups.OpenGroupAPI;
|
||||
import org.session.libsession.messaging.sending_receiving.notifications.MessageNotifier;
|
||||
import org.session.libsession.messaging.sending_receiving.notifications.PushNotificationAPI;
|
||||
import org.session.libsession.messaging.sending_receiving.pollers.ClosedGroupPoller;
|
||||
import org.session.libsession.messaging.sending_receiving.pollers.Poller;
|
||||
import org.session.libsession.messaging.threads.Address;
|
||||
import org.session.libsession.snode.SnodeAPI;
|
||||
import org.session.libsession.snode.SnodeConfiguration;
|
||||
import org.session.libsession.snode.SnodeModule;
|
||||
import org.session.libsession.utilities.IdentityKeyUtil;
|
||||
import org.session.libsession.utilities.SSKEnvironment;
|
||||
import org.session.libsession.utilities.TextSecurePreferences;
|
||||
@ -96,7 +93,6 @@ import org.webrtc.voiceengine.WebRtcAudioUtils;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.Security;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
@ -177,7 +173,7 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc
|
||||
DatabaseFactory.getStorage(this),
|
||||
DatabaseFactory.getAttachmentProvider(this),
|
||||
new SessionProtocolImpl(this));
|
||||
SnodeConfiguration.Companion.configure(apiDB, broadcaster);
|
||||
SnodeModule.Companion.configure(apiDB, broadcaster);
|
||||
if (userPublicKey != null) {
|
||||
MentionsManager.Companion.configureIfNeeded(userPublicKey, threadDB, userDB);
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ import org.session.libsession.messaging.threads.Address
|
||||
import org.session.libsession.messaging.utilities.MessageWrapper
|
||||
import org.session.libsession.snode.RawResponsePromise
|
||||
import org.session.libsession.snode.SnodeAPI
|
||||
import org.session.libsession.snode.SnodeConfiguration
|
||||
import org.session.libsession.snode.SnodeModule
|
||||
import org.session.libsession.snode.SnodeMessage
|
||||
import org.session.libsession.utilities.SSKEnvironment
|
||||
import org.session.libsignal.service.internal.push.PushTransportDetails
|
||||
@ -82,7 +82,7 @@ object MessageSender {
|
||||
fun handleFailure(error: Exception) {
|
||||
handleFailedMessageSend(message, error)
|
||||
if (destination is Destination.Contact && message is VisibleMessage && !isSelfSend) {
|
||||
SnodeConfiguration.shared.broadcaster.broadcast("messageFailed", message.sentTimestamp!!)
|
||||
SnodeModule.shared.broadcaster.broadcast("messageFailed", message.sentTimestamp!!)
|
||||
}
|
||||
deferred.reject(error)
|
||||
}
|
||||
@ -147,12 +147,12 @@ object MessageSender {
|
||||
val wrappedMessage = MessageWrapper.wrap(kind, message.sentTimestamp!!, senderPublicKey, ciphertext)
|
||||
// Send the result
|
||||
if (destination is Destination.Contact && message is VisibleMessage && !isSelfSend) {
|
||||
SnodeConfiguration.shared.broadcaster.broadcast("calculatingPoW", message.sentTimestamp!!)
|
||||
SnodeModule.shared.broadcaster.broadcast("calculatingPoW", message.sentTimestamp!!)
|
||||
}
|
||||
val base64EncodedData = Base64.encodeBytes(wrappedMessage)
|
||||
val snodeMessage = SnodeMessage(message.recipient!!, base64EncodedData, message.ttl, message.sentTimestamp!!)
|
||||
if (destination is Destination.Contact && message is VisibleMessage && !isSelfSend) {
|
||||
SnodeConfiguration.shared.broadcaster.broadcast("sendingMessage", message.sentTimestamp!!)
|
||||
SnodeModule.shared.broadcaster.broadcast("sendingMessage", message.sentTimestamp!!)
|
||||
}
|
||||
SnodeAPI.sendMessage(snodeMessage).success { promises: Set<RawResponsePromise> ->
|
||||
var isSuccess = false
|
||||
@ -163,7 +163,7 @@ object MessageSender {
|
||||
if (isSuccess) { return@success } // Succeed as soon as the first promise succeeds
|
||||
isSuccess = true
|
||||
if (destination is Destination.Contact && message is VisibleMessage && !isSelfSend) {
|
||||
SnodeConfiguration.shared.broadcaster.broadcast("messageSent", message.sentTimestamp!!)
|
||||
SnodeModule.shared.broadcaster.broadcast("messageSent", message.sentTimestamp!!)
|
||||
}
|
||||
handleSuccessfulMessageSend(message, destination, isSyncMessage)
|
||||
var shouldNotify = (message is VisibleMessage && !isSyncMessage)
|
||||
|
@ -7,7 +7,7 @@ import org.session.libsession.messaging.jobs.JobQueue
|
||||
import org.session.libsession.messaging.jobs.MessageReceiveJob
|
||||
import org.session.libsession.messaging.utilities.MessageWrapper
|
||||
import org.session.libsession.snode.SnodeAPI
|
||||
import org.session.libsession.snode.SnodeConfiguration
|
||||
import org.session.libsession.snode.SnodeModule
|
||||
import org.session.libsignal.service.loki.api.Snode
|
||||
import org.session.libsignal.utilities.Base64
|
||||
import org.session.libsignal.utilities.logging.Log
|
||||
@ -47,9 +47,9 @@ class Poller {
|
||||
private fun setUpPolling() {
|
||||
if (!hasStarted) { return; }
|
||||
val thread = Thread.currentThread()
|
||||
SnodeAPI.getSwarm(userPublicKey).bind(SnodeAPI.messagePollingContext) {
|
||||
SnodeAPI.getSwarm(userPublicKey).bind {
|
||||
usedSnodes.clear()
|
||||
val deferred = deferred<Unit, Exception>(SnodeAPI.messagePollingContext)
|
||||
val deferred = deferred<Unit, Exception>()
|
||||
pollNextSnode(deferred)
|
||||
deferred.promise
|
||||
}.always {
|
||||
@ -63,7 +63,7 @@ class Poller {
|
||||
}
|
||||
|
||||
private fun pollNextSnode(deferred: Deferred<Unit, Exception>) {
|
||||
val swarm = SnodeConfiguration.shared.storage.getSwarm(userPublicKey) ?: setOf()
|
||||
val swarm = SnodeModule.shared.storage.getSwarm(userPublicKey) ?: setOf()
|
||||
val unusedSnodes = swarm.subtract(usedSnodes)
|
||||
if (unusedSnodes.isNotEmpty()) {
|
||||
val index = SecureRandom().nextInt(unusedSnodes.size)
|
||||
@ -87,7 +87,7 @@ class Poller {
|
||||
|
||||
private fun poll(snode: Snode, deferred: Deferred<Unit, Exception>): Promise<Unit, Exception> {
|
||||
if (!hasStarted) { return Promise.ofFail(PromiseCanceledException()) }
|
||||
return SnodeAPI.getRawMessages(snode, userPublicKey).bind(SnodeAPI.messagePollingContext) { rawResponse ->
|
||||
return SnodeAPI.getRawMessages(snode, userPublicKey).bind { rawResponse ->
|
||||
isCaughtUp = true
|
||||
if (deferred.promise.isDone()) {
|
||||
task { Unit } // The long polling connection has been canceled; don't recurse
|
||||
|
@ -83,7 +83,7 @@ open class DotNetAPI {
|
||||
Log.d("Loki", "Requesting auth token for server: $server.")
|
||||
val userKeyPair = MessagingConfiguration.shared.storage.getUserKeyPair() ?: throw Error.Generic
|
||||
val parameters: Map<String, Any> = mapOf( "pubKey" to userKeyPair.first )
|
||||
return execute(HTTPVerb.GET, server, "loki/v1/get_challenge", false, parameters).map(SnodeAPI.sharedContext) { json ->
|
||||
return execute(HTTPVerb.GET, server, "loki/v1/get_challenge", false, parameters).map { json ->
|
||||
try {
|
||||
val base64EncodedChallenge = json["cipherText64"] as String
|
||||
val challenge = Base64.decode(base64EncodedChallenge)
|
||||
|
@ -17,6 +17,7 @@ import org.session.libsession.utilities.AESGCM.EncryptionResult
|
||||
import org.session.libsignal.utilities.ThreadUtils
|
||||
import org.session.libsession.utilities.getBodyForOnionRequest
|
||||
import org.session.libsession.utilities.getHeadersForOnionRequest
|
||||
import org.session.libsignal.service.loki.database.LokiAPIDatabaseProtocol
|
||||
import org.session.libsignal.service.loki.utilities.*
|
||||
|
||||
private typealias Path = List<Snode>
|
||||
@ -25,16 +26,21 @@ private typealias Path = List<Snode>
|
||||
* See the "Onion Requests" section of [The Session Whitepaper](https://arxiv.org/pdf/2002.04609.pdf) for more information.
|
||||
*/
|
||||
object OnionRequestAPI {
|
||||
private val database: LokiAPIDatabaseProtocol
|
||||
get() = SnodeModule.shared.storage
|
||||
private val broadcaster: Broadcaster
|
||||
get() = SnodeModule.shared.broadcaster
|
||||
private val pathFailureCount = mutableMapOf<Path, Int>()
|
||||
private val snodeFailureCount = mutableMapOf<Snode, Int>()
|
||||
|
||||
var guardSnodes = setOf<Snode>()
|
||||
var paths: List<Path> // Not a set to ensure we consistently show the same path to the user
|
||||
get() = SnodeAPI.database.getOnionRequestPaths()
|
||||
get() = database.getOnionRequestPaths()
|
||||
set(newValue) {
|
||||
if (newValue.isEmpty()) {
|
||||
SnodeAPI.database.clearOnionRequestPaths()
|
||||
database.clearOnionRequestPaths()
|
||||
} else {
|
||||
SnodeAPI.database.setOnionRequestPaths(newValue)
|
||||
database.setOnionRequestPaths(newValue)
|
||||
}
|
||||
}
|
||||
|
||||
@ -51,16 +57,15 @@ object OnionRequestAPI {
|
||||
* The number of times a snode can fail before it's replaced.
|
||||
*/
|
||||
private const val snodeFailureThreshold = 1
|
||||
/**
|
||||
* The number of paths to maintain.
|
||||
*/
|
||||
const val targetPathCount = 2 // A main path and a backup path for the case where the target snode is in the main path
|
||||
|
||||
/**
|
||||
* The number of guard snodes required to maintain `targetPathCount` paths.
|
||||
*/
|
||||
private val targetGuardSnodeCount
|
||||
get() = targetPathCount // One per path
|
||||
/**
|
||||
* The number of paths to maintain.
|
||||
*/
|
||||
const val targetPathCount = 2 // A main path and a backup path for the case where the target snode is in the main path
|
||||
// endregion
|
||||
|
||||
class HTTPRequestFailedAtDestinationException(val statusCode: Int, val json: Map<*, *>)
|
||||
@ -113,7 +118,7 @@ object OnionRequestAPI {
|
||||
return Promise.of(guardSnodes)
|
||||
} else {
|
||||
Log.d("Loki", "Populating guard snode cache.")
|
||||
return SnodeAPI.getRandomSnode().bind(SnodeAPI.sharedContext) { // Just used to populate the snode pool
|
||||
return SnodeAPI.getRandomSnode().bind { // Just used to populate the snode pool
|
||||
var unusedSnodes = SnodeAPI.snodePool.minus(reusableGuardSnodes)
|
||||
val reusableGuardSnodeCount = reusableGuardSnodes.count()
|
||||
if (unusedSnodes.count() < (targetGuardSnodeCount - reusableGuardSnodeCount)) { throw InsufficientSnodesException() }
|
||||
@ -138,7 +143,7 @@ object OnionRequestAPI {
|
||||
return deferred.promise
|
||||
}
|
||||
val promises = (0 until (targetGuardSnodeCount - reusableGuardSnodeCount)).map { getGuardSnode() }
|
||||
all(promises).map(SnodeAPI.sharedContext) { guardSnodes ->
|
||||
all(promises).map { guardSnodes ->
|
||||
val guardSnodesAsSet = (guardSnodes + reusableGuardSnodes).toSet()
|
||||
OnionRequestAPI.guardSnodes = guardSnodesAsSet
|
||||
guardSnodesAsSet
|
||||
@ -153,10 +158,10 @@ object OnionRequestAPI {
|
||||
*/
|
||||
private fun buildPaths(reusablePaths: List<Path>): Promise<List<Path>, Exception> {
|
||||
Log.d("Loki", "Building onion request paths.")
|
||||
SnodeAPI.broadcaster.broadcast("buildingPaths")
|
||||
return SnodeAPI.getRandomSnode().bind(SnodeAPI.sharedContext) { // Just used to populate the snode pool
|
||||
broadcaster.broadcast("buildingPaths")
|
||||
return SnodeAPI.getRandomSnode().bind { // Just used to populate the snode pool
|
||||
val reusableGuardSnodes = reusablePaths.map { it[0] }
|
||||
getGuardSnodes(reusableGuardSnodes).map(SnodeAPI.sharedContext) { guardSnodes ->
|
||||
getGuardSnodes(reusableGuardSnodes).map { guardSnodes ->
|
||||
var unusedSnodes = SnodeAPI.snodePool.minus(guardSnodes).minus(reusablePaths.flatten())
|
||||
val reusableGuardSnodeCount = reusableGuardSnodes.count()
|
||||
val pathSnodeCount = (targetGuardSnodeCount - reusableGuardSnodeCount) * pathSize - (targetGuardSnodeCount - reusableGuardSnodeCount)
|
||||
@ -173,7 +178,7 @@ object OnionRequestAPI {
|
||||
}
|
||||
}.map { paths ->
|
||||
OnionRequestAPI.paths = paths + reusablePaths
|
||||
SnodeAPI.broadcaster.broadcast("pathsBuilt")
|
||||
broadcaster.broadcast("pathsBuilt")
|
||||
paths
|
||||
}
|
||||
}
|
||||
@ -207,12 +212,12 @@ object OnionRequestAPI {
|
||||
buildPaths(paths) // Re-build paths in the background
|
||||
return Promise.of(getPath(paths))
|
||||
} else {
|
||||
return buildPaths(paths).map(SnodeAPI.sharedContext) { newPaths ->
|
||||
return buildPaths(paths).map { newPaths ->
|
||||
getPath(newPaths)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return buildPaths(listOf()).map(SnodeAPI.sharedContext) { newPaths ->
|
||||
return buildPaths(listOf()).map { newPaths ->
|
||||
getPath(newPaths)
|
||||
}
|
||||
}
|
||||
@ -263,10 +268,10 @@ object OnionRequestAPI {
|
||||
is Destination.Snode -> destination.snode
|
||||
is Destination.Server -> null
|
||||
}
|
||||
return getPath(snodeToExclude).bind(SnodeAPI.sharedContext) { path ->
|
||||
return getPath(snodeToExclude).bind { path ->
|
||||
guardSnode = path.first()
|
||||
// Encrypt in reverse order, i.e. the destination first
|
||||
OnionRequestEncryption.encryptPayloadForDestination(payload, destination).bind(SnodeAPI.sharedContext) { r ->
|
||||
OnionRequestEncryption.encryptPayloadForDestination(payload, destination).bind { r ->
|
||||
destinationSymmetricKey = r.symmetricKey
|
||||
// Recursively encrypt the layers of the onion (again in reverse order)
|
||||
encryptionResult = r
|
||||
@ -278,7 +283,7 @@ object OnionRequestAPI {
|
||||
} else {
|
||||
val lhs = Destination.Snode(path.last())
|
||||
path = path.dropLast(1)
|
||||
return OnionRequestEncryption.encryptHop(lhs, rhs, encryptionResult).bind(SnodeAPI.sharedContext) { r ->
|
||||
return OnionRequestEncryption.encryptHop(lhs, rhs, encryptionResult).bind { r ->
|
||||
encryptionResult = r
|
||||
rhs = lhs
|
||||
addLayer()
|
||||
@ -287,7 +292,7 @@ object OnionRequestAPI {
|
||||
}
|
||||
addLayer()
|
||||
}
|
||||
}.map(SnodeAPI.sharedContext) { OnionBuildingResult(guardSnode, encryptionResult, destinationSymmetricKey) }
|
||||
}.map { OnionBuildingResult(guardSnode, encryptionResult, destinationSymmetricKey) }
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,17 +1,10 @@
|
||||
package org.session.libsession.snode
|
||||
|
||||
class Snode(val address: String, val port: Int, val publicKeySet: KeySet?) {
|
||||
|
||||
val ip: String get() = address.removePrefix("https://")
|
||||
|
||||
internal enum class Method(val rawValue: String) {
|
||||
/**
|
||||
* Only supported by snode targets.
|
||||
*/
|
||||
GetSwarm("get_snodes_for_pubkey"),
|
||||
/**
|
||||
* Only supported by snode targets.
|
||||
*/
|
||||
GetMessages("retrieve"),
|
||||
SendMessage("store")
|
||||
}
|
||||
|
@ -19,12 +19,10 @@ import org.session.libsignal.utilities.logging.Log
|
||||
import java.security.SecureRandom
|
||||
|
||||
object SnodeAPI {
|
||||
val database: LokiAPIDatabaseProtocol
|
||||
get() = SnodeConfiguration.shared.storage
|
||||
val broadcaster: Broadcaster
|
||||
get() = SnodeConfiguration.shared.broadcaster
|
||||
val sharedContext = Kovenant.createContext()
|
||||
val messagePollingContext = Kovenant.createContext()
|
||||
private val database: LokiAPIDatabaseProtocol
|
||||
get() = SnodeModule.shared.storage
|
||||
private val broadcaster: Broadcaster
|
||||
get() = SnodeModule.shared.broadcaster
|
||||
|
||||
internal var snodeFailureCount: MutableMap<Snode, Int> = mutableMapOf()
|
||||
internal var snodePool: Set<Snode>
|
||||
@ -33,30 +31,27 @@ object SnodeAPI {
|
||||
|
||||
// Settings
|
||||
private val maxRetryCount = 6
|
||||
private val minimumSnodePoolCount = 64
|
||||
private val minimumSnodePoolCount = 24
|
||||
private val minimumSwarmSnodeCount = 2
|
||||
|
||||
// use port 4433 if API level can handle network security config and enforce pinned certificates
|
||||
private val seedPort = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) 443 else 4433
|
||||
// Use port 4433 if the API level can handle the network security configuration and enforce pinned certificates
|
||||
private val seedNodePort = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) 443 else 4433
|
||||
private val seedNodePool by lazy {
|
||||
if (useTestnet) {
|
||||
setOf( "http://public.loki.foundation:38157" )
|
||||
} else {
|
||||
setOf( "https://storage.seed1.loki.network:$seedPort", "https://storage.seed3.loki.network:$seedPort", "https://public.loki.foundation:$seedPort" )
|
||||
setOf( "https://storage.seed1.loki.network:$seedNodePort", "https://storage.seed3.loki.network:$seedNodePort", "https://public.loki.foundation:$seedNodePort" )
|
||||
}
|
||||
}
|
||||
private val snodeFailureThreshold = 4
|
||||
private val targetSwarmSnodeCount = 2
|
||||
private val useOnionRequests = true
|
||||
|
||||
internal val useTestnet = false
|
||||
internal var powDifficulty = 1
|
||||
internal val useTestnet = true
|
||||
|
||||
// Error
|
||||
internal sealed class Error(val description: String) : Exception(description) {
|
||||
object Generic : Error("An error occurred.")
|
||||
object ClockOutOfSync : Error("The user's clock is out of sync with the service node network.")
|
||||
object RandomSnodePoolUpdatingFailed : Error("Failed to update random service node pool.")
|
||||
object ClockOutOfSync : Error("Your clock is out of sync with the Service Node network.")
|
||||
}
|
||||
|
||||
// Internal API
|
||||
@ -94,12 +89,12 @@ object SnodeAPI {
|
||||
val parameters = mapOf(
|
||||
"method" to "get_n_service_nodes",
|
||||
"params" to mapOf(
|
||||
"active_only" to true,
|
||||
"fields" to mapOf( "public_ip" to true, "storage_port" to true, "pubkey_x25519" to true, "pubkey_ed25519" to true )
|
||||
"active_only" to true,
|
||||
"fields" to mapOf( "public_ip" to true, "storage_port" to true, "pubkey_x25519" to true, "pubkey_ed25519" to true )
|
||||
)
|
||||
)
|
||||
val deferred = deferred<Snode, Exception>()
|
||||
deferred<org.session.libsignal.service.loki.api.Snode, Exception>(SnodeAPI.sharedContext)
|
||||
deferred<Snode, Exception>()
|
||||
ThreadUtils.queue {
|
||||
try {
|
||||
val json = HTTP.execute(HTTP.Verb.POST, url, parameters, useSeedNodeConnection = true)
|
||||
@ -170,7 +165,7 @@ object SnodeAPI {
|
||||
val parameters = mapOf( "pubKey" to if (useTestnet) publicKey.removing05PrefixIfNeeded() else publicKey )
|
||||
return getRandomSnode().bind {
|
||||
invoke(Snode.Method.GetSwarm, it, publicKey, parameters)
|
||||
}.map(sharedContext) {
|
||||
}.map {
|
||||
parseSnodes(it).toSet()
|
||||
}.success {
|
||||
database.setSwarm(publicKey, it)
|
||||
@ -186,8 +181,8 @@ object SnodeAPI {
|
||||
|
||||
fun getMessages(publicKey: String): MessageListPromise {
|
||||
return retryIfNeeded(maxRetryCount) {
|
||||
getSingleTargetSnode(publicKey).bind(messagePollingContext) { snode ->
|
||||
getRawMessages(snode, publicKey).map(messagePollingContext) { parseRawMessagesResponse(it, snode, publicKey) }
|
||||
getSingleTargetSnode(publicKey).bind { snode ->
|
||||
getRawMessages(snode, publicKey).map { parseRawMessagesResponse(it, snode, publicKey) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -199,19 +194,7 @@ object SnodeAPI {
|
||||
swarm.map { snode ->
|
||||
val parameters = message.toJSON()
|
||||
retryIfNeeded(maxRetryCount) {
|
||||
invoke(Snode.Method.SendMessage, snode, destination, parameters).map { rawResponse ->
|
||||
val json = rawResponse as? Map<*, *>
|
||||
val powDifficulty = json?.get("difficulty") as? Int
|
||||
if (powDifficulty != null) {
|
||||
if (powDifficulty != SnodeAPI.powDifficulty && powDifficulty < 100) {
|
||||
Log.d("Loki", "Setting proof of work difficulty to $powDifficulty (snode: $snode).")
|
||||
SnodeAPI.powDifficulty = powDifficulty
|
||||
}
|
||||
} else {
|
||||
Log.d("Loki", "Failed to update proof of work difficulty from: ${rawResponse.prettifiedDescription()}.")
|
||||
}
|
||||
rawResponse
|
||||
}
|
||||
invoke(Snode.Method.SendMessage, snode, destination, parameters)
|
||||
}
|
||||
}.toSet()
|
||||
}
|
||||
@ -256,7 +239,6 @@ object SnodeAPI {
|
||||
private fun updateLastMessageHashValueIfPossible(snode: Snode, publicKey: String, rawMessages: List<*>) {
|
||||
val lastMessageAsJSON = rawMessages.lastOrNull() as? Map<*, *>
|
||||
val hashValue = lastMessageAsJSON?.get("hash") as? String
|
||||
val expiration = lastMessageAsJSON?.get("expiration") as? Int
|
||||
if (hashValue != null) {
|
||||
database.setLastMessageHashValue(snode, publicKey, hashValue)
|
||||
} else if (rawMessages.isNotEmpty()) {
|
||||
@ -316,20 +298,6 @@ object SnodeAPI {
|
||||
Log.d("Loki", "Got a 421 without an associated public key.")
|
||||
}
|
||||
}
|
||||
432 -> {
|
||||
// The PoW difficulty is too low
|
||||
val powDifficulty = json?.get("difficulty") as? Int
|
||||
if (powDifficulty != null) {
|
||||
if (powDifficulty < 100) {
|
||||
Log.d("Loki", "Setting proof of work difficulty to $powDifficulty (snode: $snode).")
|
||||
SnodeAPI.powDifficulty = powDifficulty
|
||||
} else {
|
||||
handleBadSnode()
|
||||
}
|
||||
} else {
|
||||
Log.d("Loki", "Failed to update proof of work difficulty.")
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
handleBadSnode()
|
||||
Log.d("Loki", "Unhandled response code: ${statusCode}.")
|
||||
@ -338,8 +306,6 @@ object SnodeAPI {
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Type Aliases
|
||||
|
@ -12,12 +12,14 @@ data class SnodeMessage(
|
||||
// When the proof of work was calculated.
|
||||
val timestamp: Long
|
||||
) {
|
||||
|
||||
internal fun toJSON(): Map<String, String> {
|
||||
return mutableMapOf(
|
||||
"pubKey" to if (SnodeAPI.useTestnet) recipient.removing05PrefixIfNeeded() else recipient,
|
||||
"data" to data,
|
||||
"ttl" to ttl.toString(),
|
||||
"timestamp" to timestamp.toString(),
|
||||
"nonce" to "")
|
||||
return mapOf(
|
||||
"pubKey" to if (SnodeAPI.useTestnet) recipient.removing05PrefixIfNeeded() else recipient,
|
||||
"data" to data,
|
||||
"ttl" to ttl.toString(),
|
||||
"timestamp" to timestamp.toString(),
|
||||
"nonce" to ""
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -3,13 +3,14 @@ package org.session.libsession.snode
|
||||
import org.session.libsignal.service.loki.database.LokiAPIDatabaseProtocol
|
||||
import org.session.libsignal.service.loki.utilities.Broadcaster
|
||||
|
||||
class SnodeConfiguration(val storage: LokiAPIDatabaseProtocol, val broadcaster: Broadcaster) {
|
||||
class SnodeModule(val storage: LokiAPIDatabaseProtocol, val broadcaster: Broadcaster) {
|
||||
|
||||
companion object {
|
||||
lateinit var shared: SnodeConfiguration
|
||||
lateinit var shared: SnodeModule
|
||||
|
||||
fun configure(storage: LokiAPIDatabaseProtocol, broadcaster: Broadcaster) {
|
||||
if (Companion::shared.isInitialized) { return }
|
||||
shared = SnodeConfiguration(storage, broadcaster)
|
||||
shared = SnodeModule(storage, broadcaster)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package org.session.libsession.snode
|
||||
|
||||
interface SnodeStorageProtocol {
|
||||
|
||||
fun getSnodePool(): Set<Snode>
|
||||
fun setSnodePool(newValue: Set<Snode>)
|
||||
fun getOnionRequestPaths(): List<List<Snode>>
|
||||
|
Loading…
x
Reference in New Issue
Block a user