From 3c8302f7a4ce226096b2cac79b0c81d11fee949a Mon Sep 17 00:00:00 2001
From: bemusementpark <bemusementpark>
Date: Sat, 3 Aug 2024 21:19:31 +0930
Subject: [PATCH] Optimise SnodeAPI further

---
 .../java/org/session/libsession/snode/SnodeAPI.kt     | 11 +++++------
 .../java/org/session/libsignal/utilities/Snode.kt     |  6 +++---
 2 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/libsession/src/main/java/org/session/libsession/snode/SnodeAPI.kt b/libsession/src/main/java/org/session/libsession/snode/SnodeAPI.kt
index 6d1ffaa5c0..4d59669d1c 100644
--- a/libsession/src/main/java/org/session/libsession/snode/SnodeAPI.kt
+++ b/libsession/src/main/java/org/session/libsession/snode/SnodeAPI.kt
@@ -455,7 +455,7 @@ object SnodeAPI {
         val hashes = messageHashes.takeIf { it.size != 1 } ?: (messageHashes + "///////////////////////////////////////////") // TODO remove this when bug is fixed on nodes.
         return retryIfNeeded(maxRetryCount) {
             val timestamp = System.currentTimeMillis() + clockOffset
-            val signData = "${Snode.Method.GetExpiries.rawValue}$timestamp${hashes.joinToString(separator = "")}".toByteArray()
+            val signData = sequenceOf(Snode.Method.GetExpiries.rawValue).plus(timestamp.toString()).plus(hashes).toByteArray()
 
             val ed25519PublicKey = userEd25519KeyPair.publicKey.asHexString
             val signature = try {
@@ -499,7 +499,7 @@ object SnodeAPI {
 
         val shortenOrExtend = if (extend) "extend" else if (shorten) "shorten" else ""
 
-        val signData = "${Snode.Method.Expire.rawValue}$shortenOrExtend$newExpiry${messageHashes.joinToString(separator = "")}".toByteArray()
+        val signData = sequenceOf(Snode.Method.Expire.rawValue).plus(shortenOrExtend).plus(newExpiry.toString()).plus(messageHashes).toByteArray()
 
         val signature = try {
             signAndEncode(signData, userEd25519KeyPair)
@@ -633,7 +633,7 @@ object SnodeAPI {
             getSingleTargetSnode(userPublicKey).bind { snode ->
                 retryIfNeeded(maxRetryCount) {
                     getNetworkTime(snode).bind { (_, timestamp) ->
-                        val verificationData = (Snode.Method.DeleteAll.rawValue + Namespace.ALL + timestamp.toString()).toByteArray()
+                        val verificationData = sequenceOf(Snode.Method.DeleteAll.rawValue, Namespace.ALL, timestamp.toString()).toByteArray()
                         val deleteMessageParams = buildMap {
                             this["pubkey"] = userPublicKey
                             this["pubkey_ed25519"] = userED25519KeyPair.publicKey.asHexString
@@ -722,9 +722,8 @@ object SnodeAPI {
             if (newFailureCount >= snodeFailureThreshold) {
                 Log.d("Loki", "Failure threshold reached for: $snode; dropping it.")
                 publicKey?.let { dropSnodeFromSwarmIfNeeded(snode, it) }
-                snodePool -= snode
-                Log.d("Loki", "Snode pool count: ${snodePool.count()}.")
-                snodeFailureCount.remove(snode)
+                snodePool = (snodePool - snode).also { Log.d("Loki", "Snode pool count: ${it.count()}.") }
+                snodeFailureCount -= snode
             }
         }
         when (statusCode) {
diff --git a/libsignal/src/main/java/org/session/libsignal/utilities/Snode.kt b/libsignal/src/main/java/org/session/libsignal/utilities/Snode.kt
index cc123a8527..f918dbbf73 100644
--- a/libsignal/src/main/java/org/session/libsignal/utilities/Snode.kt
+++ b/libsignal/src/main/java/org/session/libsignal/utilities/Snode.kt
@@ -52,6 +52,8 @@ class Snode(val address: String, val port: Int, val publicKeySet: KeySet?, val v
         fun Version(value: String) = CACHE.getOrElse(value) {
             Snode.Version(value)
         }
+
+        fun Version(parts: List<Int>) = Version(parts.joinToString("."))
     }
 
     @JvmInline
@@ -66,14 +68,12 @@ class Snode(val address: String, val port: Int, val publicKeySet: KeySet?, val v
             }
         }
 
-        constructor(parts: List<Int>): this(
+        internal constructor(parts: List<Int>): this(
             parts.asSequence()
                 .map { it.toByte().toULong() }
                 .foldToVersionAsULong()
         )
 
-        constructor(value: Int): this(value.toULong())
-
         internal constructor(value: String): this(
             value.splitToSequence(".")
                 .map { it.toULongOrNull() ?: 0UL }