mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2025-11-10 07:37:12 +01:00
Improves caching of encrypted DMs:
- Migrates caching of decrypted value outside of the Event class - Removes encrypted parts of NIP-17 from the cache - Removes old NIP-04 messages from the cache - Avoids deleting new NIP-17 plain text chats from memory
This commit is contained in:
@@ -20,12 +20,14 @@
|
||||
*/
|
||||
package com.vitorpamplona.quartz.events
|
||||
|
||||
import android.util.Log
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.quartz.crypto.KeyPair
|
||||
import com.vitorpamplona.quartz.encoders.HexKey
|
||||
import com.vitorpamplona.quartz.signers.NostrSigner
|
||||
import com.vitorpamplona.quartz.signers.NostrSignerInternal
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
import com.vitorpamplona.quartz.utils.bytesUsedInMemory
|
||||
import com.vitorpamplona.quartz.utils.pointerSizeInBytes
|
||||
|
||||
@Immutable
|
||||
@@ -37,11 +39,11 @@ class GiftWrapEvent(
|
||||
content: String,
|
||||
sig: HexKey,
|
||||
) : Event(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||
@Transient private var cachedInnerEvent: Map<HexKey, Event?> = mapOf()
|
||||
@Transient var innerEventId: HexKey? = null
|
||||
|
||||
override fun countMemory(): Long =
|
||||
super.countMemory() +
|
||||
32 + (cachedInnerEvent.values.sumOf { pointerSizeInBytes + (it?.countMemory() ?: 0) }) // rough calculation
|
||||
pointerSizeInBytes + (innerEventId?.bytesUsedInMemory() ?: 0)
|
||||
|
||||
fun copyNoContent(): GiftWrapEvent {
|
||||
val copy =
|
||||
@@ -54,48 +56,38 @@ class GiftWrapEvent(
|
||||
sig,
|
||||
)
|
||||
|
||||
copy.cachedInnerEvent = cachedInnerEvent
|
||||
copy.innerEventId = innerEventId
|
||||
|
||||
return copy
|
||||
}
|
||||
|
||||
override fun isContentEncoded() = true
|
||||
|
||||
fun preCachedGift(signer: NostrSigner): Event? = cachedInnerEvent[signer.pubKey]
|
||||
|
||||
fun addToCache(
|
||||
pubKey: HexKey,
|
||||
gift: Event,
|
||||
) {
|
||||
cachedInnerEvent = cachedInnerEvent + Pair(pubKey, gift)
|
||||
}
|
||||
|
||||
@Deprecated(
|
||||
message = "Heavy caching was removed from this class due to high memory use. Cache it separatedly",
|
||||
replaceWith = ReplaceWith("unwrap"),
|
||||
)
|
||||
fun cachedGift(
|
||||
signer: NostrSigner,
|
||||
onReady: (Event) -> Unit,
|
||||
) {
|
||||
cachedInnerEvent[signer.pubKey]?.let {
|
||||
onReady(it)
|
||||
return
|
||||
}
|
||||
unwrap(signer) { gift ->
|
||||
if (gift is WrappedEvent) {
|
||||
gift.host = HostStub(this.id, this.pubKey, this.kind)
|
||||
}
|
||||
addToCache(signer.pubKey, gift)
|
||||
) = unwrap(signer, onReady)
|
||||
|
||||
onReady(gift)
|
||||
}
|
||||
}
|
||||
|
||||
private fun unwrap(
|
||||
fun unwrap(
|
||||
signer: NostrSigner,
|
||||
onReady: (Event) -> Unit,
|
||||
) {
|
||||
try {
|
||||
plainContent(signer) { onReady(fromJson(it)) }
|
||||
plainContent(signer) { giftStr ->
|
||||
val gift = fromJson(giftStr)
|
||||
if (gift is WrappedEvent) {
|
||||
gift.host = HostStub(this.id, this.pubKey, this.kind)
|
||||
}
|
||||
innerEventId = gift.id
|
||||
|
||||
onReady(gift)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
// Log.e("UnwrapError", "Couldn't Decrypt the content", e)
|
||||
Log.w("GiftWrapEvent", "Couldn't Decrypt the content", e)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ import com.vitorpamplona.quartz.encoders.HexKey
|
||||
import com.vitorpamplona.quartz.encoders.toHexKey
|
||||
import com.vitorpamplona.quartz.signers.NostrSigner
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
import com.vitorpamplona.quartz.utils.bytesUsedInMemory
|
||||
import com.vitorpamplona.quartz.utils.pointerSizeInBytes
|
||||
|
||||
@Immutable
|
||||
@@ -38,11 +39,11 @@ class SealedGossipEvent(
|
||||
content: String,
|
||||
sig: HexKey,
|
||||
) : WrappedEvent(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||
@Transient private var cachedInnerEvent: Map<HexKey, Event?> = mapOf()
|
||||
@Transient var innerEventId: HexKey? = null
|
||||
|
||||
override fun countMemory(): Long =
|
||||
super.countMemory() +
|
||||
pointerSizeInBytes + cachedInnerEvent.values.sumOf { pointerSizeInBytes + (it?.countMemory() ?: 0) }
|
||||
pointerSizeInBytes + (innerEventId?.bytesUsedInMemory() ?: 0)
|
||||
|
||||
fun copyNoContent(): SealedGossipEvent {
|
||||
val copy =
|
||||
@@ -55,51 +56,38 @@ class SealedGossipEvent(
|
||||
sig,
|
||||
)
|
||||
|
||||
copy.cachedInnerEvent = cachedInnerEvent
|
||||
copy.host = host
|
||||
copy.innerEventId = innerEventId
|
||||
|
||||
return copy
|
||||
}
|
||||
|
||||
override fun isContentEncoded() = true
|
||||
|
||||
fun preCachedGossip(signer: NostrSigner): Event? = cachedInnerEvent[signer.pubKey]
|
||||
|
||||
fun addToCache(
|
||||
pubKey: HexKey,
|
||||
gift: Event,
|
||||
) {
|
||||
cachedInnerEvent = cachedInnerEvent + Pair(pubKey, gift)
|
||||
}
|
||||
|
||||
@Deprecated(
|
||||
message = "Heavy caching was removed from this class due to high memory use. Cache it separatedly",
|
||||
replaceWith = ReplaceWith("unseal"),
|
||||
)
|
||||
fun cachedGossip(
|
||||
signer: NostrSigner,
|
||||
onReady: (Event) -> Unit,
|
||||
) {
|
||||
cachedInnerEvent[signer.pubKey]?.let {
|
||||
onReady(it)
|
||||
return
|
||||
}
|
||||
) = unseal(signer, onReady)
|
||||
|
||||
unseal(signer) { gossip ->
|
||||
val event = gossip.mergeWith(this)
|
||||
if (event is WrappedEvent) {
|
||||
event.host = host ?: HostStub(this.id, this.pubKey, this.kind)
|
||||
}
|
||||
addToCache(signer.pubKey, event)
|
||||
|
||||
onReady(event)
|
||||
}
|
||||
}
|
||||
|
||||
private fun unseal(
|
||||
fun unseal(
|
||||
signer: NostrSigner,
|
||||
onReady: (Gossip) -> Unit,
|
||||
onReady: (Event) -> Unit,
|
||||
) {
|
||||
try {
|
||||
plainContent(signer) {
|
||||
try {
|
||||
onReady(Gossip.fromJson(it))
|
||||
val gossip = Gossip.fromJson(it)
|
||||
val event = gossip.mergeWith(this)
|
||||
if (event is WrappedEvent) {
|
||||
event.host = host ?: HostStub(this.id, this.pubKey, this.kind)
|
||||
}
|
||||
innerEventId = event.id
|
||||
|
||||
onReady(event)
|
||||
} catch (e: Exception) {
|
||||
Log.w("GossipEvent", "Fail to decrypt or parse Gossip", e)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user