- Moves away from persistent collections (slower)

- Adds a hashcode cash for spam and blocked user public keys
- Adds a cache for isHidden
- Moves isHidden composable from LiveData to Flow
This commit is contained in:
Vitor Pamplona
2024-06-12 15:05:46 -04:00
parent a716d13c69
commit 42408978c4
7 changed files with 384 additions and 486 deletions
@@ -59,14 +59,13 @@ open class Event(
) : EventInterface {
override fun isContentEncoded() = false
override fun countMemory(): Long {
return 12L +
override fun countMemory(): Long =
12L +
id.bytesUsedInMemory() +
pubKey.bytesUsedInMemory() +
tags.sumOf { it.sumOf { it.bytesUsedInMemory() } } +
content.bytesUsedInMemory() +
sig.bytesUsedInMemory()
}
override fun id(): HexKey = id
@@ -152,8 +151,8 @@ open class Event(
override fun hasZapSplitSetup() = tags.any { it.size > 1 && it[0] == "zap" }
override fun zapSplitSetup(): List<ZapSplitSetup> {
return tags
override fun zapSplitSetup(): List<ZapSplitSetup> =
tags
.filter { it.size > 1 && it[0] == "zap" }
.mapNotNull {
val isLnAddress = it[0].contains("@") || it[0].startsWith("LNURL", true)
@@ -170,7 +169,6 @@ open class Event(
null
}
}
}
override fun taggedAddresses() =
tags
@@ -272,29 +270,23 @@ open class Event(
return rank
}
override fun getGeoHash(): String? {
return tags.firstOrNull { it.size > 1 && it[0] == "g" }?.get(1)?.ifBlank { null }
}
override fun getGeoHash(): String? = tags.firstOrNull { it.size > 1 && it[0] == "g" }?.get(1)?.ifBlank { null }
override fun getReward(): BigDecimal? {
return try {
override fun getReward(): BigDecimal? =
try {
tags.firstOrNull { it.size > 1 && it[0] == "reward" }?.get(1)?.let { BigDecimal(it) }
} catch (e: Exception) {
null
}
}
open fun toNIP19(): String {
return if (this is AddressableEvent) {
open fun toNIP19(): String =
if (this is AddressableEvent) {
ATag(kind, pubKey, dTag(), null).toNAddr()
} else {
Nip19Bech32.createNEvent(id, pubKey, kind, null)
}
}
fun toNostrUri(): String {
return "nostr:${toNIP19()}"
}
fun toNostrUri(): String = "nostr:${toNIP19()}"
fun hasCorrectIDHash(): Boolean {
if (id.isEmpty()) return false
@@ -320,8 +312,7 @@ open class Event(
| Event: ${toJson()}
| Actual ID: $id
| Generated: ${generateId()}
"""
.trimIndent(),
""".trimIndent(),
)
}
if (!hasVerifiedSignature()) {
@@ -329,22 +320,17 @@ open class Event(
}
}
override fun hasValidSignature(): Boolean {
return try {
override fun hasValidSignature(): Boolean =
try {
hasCorrectIDHash() && hasVerifiedSignature()
} catch (e: Exception) {
Log.w("Event", "Event $id does not have a valid signature: ${toJson()}", e)
false
}
}
fun makeJsonForId(): String {
return makeJsonForId(pubKey, createdAt, kind, tags, content)
}
fun makeJsonForId(): String = makeJsonForId(pubKey, createdAt, kind, tags, content)
fun generateId(): String {
return CryptoUtils.sha256(makeJsonForId().toByteArray()).toHexKey()
}
fun generateId(): String = CryptoUtils.sha256(makeJsonForId().toByteArray()).toHexKey()
fun generateId2(): String {
val sha256 = MessageDigest.getInstance("SHA-256")
@@ -356,9 +342,7 @@ open class Event(
override fun deserialize(
jp: JsonParser,
ctxt: DeserializationContext,
): Event {
return fromJson(jp.codec.readTree(jp))
}
): Event = fromJson(jp.codec.readTree(jp))
}
private class GossipDeserializer : StdDeserializer<Gossip>(Gossip::class.java) {
@@ -460,8 +444,8 @@ open class Event(
.addDeserializer(Request::class.java, RequestDeserializer()),
)
fun fromJson(jsonObject: JsonNode): Event {
return EventFactory.create(
fun fromJson(jsonObject: JsonNode): Event =
EventFactory.create(
id = jsonObject.get("id").asText().intern(),
pubKey = jsonObject.get("pubkey").asText().intern(),
createdAt = jsonObject.get("created_at").asLong(),
@@ -473,11 +457,8 @@ open class Event(
content = jsonObject.get("content").asText(),
sig = jsonObject.get("sig").asText(),
)
}
private inline fun <reified R> JsonNode.toTypedArray(transform: (JsonNode) -> R): Array<R> {
return Array(size()) { transform(get(it)) }
}
private inline fun <reified R> JsonNode.toTypedArray(transform: (JsonNode) -> R): Array<R> = Array(size()) { transform(get(it)) }
fun fromJson(json: String): Event = mapper.readValue(json, Event::class.java)
@@ -518,9 +499,7 @@ open class Event(
kind: Int,
tags: Array<Array<String>>,
content: String,
): ByteArray {
return CryptoUtils.sha256(makeJsonForId(pubKey, createdAt, kind, tags, content).toByteArray())
}
): ByteArray = CryptoUtils.sha256(makeJsonForId(pubKey, createdAt, kind, tags, content).toByteArray())
fun create(
signer: NostrSigner,
@@ -529,9 +508,7 @@ open class Event(
content: String = "",
createdAt: Long = TimeUtils.now(),
onReady: (Event) -> Unit,
) {
return signer.sign(createdAt, kind, tags, content, onReady)
}
) = signer.sign(createdAt, kind, tags, content, onReady)
}
}
@@ -572,7 +549,8 @@ open class BaseAddressableEvent(
tags: Array<Array<String>>,
content: String,
sig: HexKey,
) : Event(id, pubKey, createdAt, kind, tags, content, sig), AddressableEvent {
) : Event(id, pubKey, createdAt, kind, tags, content, sig),
AddressableEvent {
override fun dTag() = tags.firstOrNull { it.size > 1 && it[0] == "d" }?.get(1) ?: ""
override fun address() = ATag(kind, pubKey, dTag(), null)
@@ -25,7 +25,6 @@ import com.vitorpamplona.quartz.encoders.HexKey
import com.vitorpamplona.quartz.signers.NostrSigner
import com.vitorpamplona.quartz.utils.TimeUtils
import kotlinx.collections.immutable.ImmutableSet
import kotlinx.collections.immutable.persistentSetOf
@Immutable
class PeopleListEvent(
@@ -71,9 +70,9 @@ class PeopleListEvent(
}
@Immutable
data class UsersAndWords(
val users: ImmutableSet<String> = persistentSetOf(),
val words: ImmutableSet<String> = persistentSetOf(),
class UsersAndWords(
val users: Set<String> = setOf(),
val words: Set<String> = setOf(),
)
fun publicAndPrivateUsersAndWords(
@@ -120,9 +119,7 @@ class PeopleListEvent(
const val BLOCK_LIST_D_TAG = "mute"
const val ALT = "List of people"
fun blockListFor(pubKeyHex: HexKey): String {
return "30000:$pubKeyHex:$BLOCK_LIST_D_TAG"
}
fun blockListFor(pubKeyHex: HexKey): String = "30000:$pubKeyHex:$BLOCK_LIST_D_TAG"
fun createListWithTag(
name: String,
@@ -161,9 +158,7 @@ class PeopleListEvent(
signer: NostrSigner,
createdAt: Long = TimeUtils.now(),
onReady: (PeopleListEvent) -> Unit,
) {
return createListWithTag(name, "p", pubKeyHex, isPrivate, signer, createdAt, onReady)
}
) = createListWithTag(name, "p", pubKeyHex, isPrivate, signer, createdAt, onReady)
fun createListWithWord(
name: String,
@@ -172,9 +167,7 @@ class PeopleListEvent(
signer: NostrSigner,
createdAt: Long = TimeUtils.now(),
onReady: (PeopleListEvent) -> Unit,
) {
return createListWithTag(name, "word", word, isPrivate, signer, createdAt, onReady)
}
) = createListWithTag(name, "word", word, isPrivate, signer, createdAt, onReady)
fun addUsers(
earlierVersion: PeopleListEvent,
@@ -223,9 +216,7 @@ class PeopleListEvent(
signer: NostrSigner,
createdAt: Long = TimeUtils.now(),
onReady: (PeopleListEvent) -> Unit,
) {
return addTag(earlierVersion, "word", word, isPrivate, signer, createdAt, onReady)
}
) = addTag(earlierVersion, "word", word, isPrivate, signer, createdAt, onReady)
fun addUser(
earlierVersion: PeopleListEvent,
@@ -234,9 +225,7 @@ class PeopleListEvent(
signer: NostrSigner,
createdAt: Long = TimeUtils.now(),
onReady: (PeopleListEvent) -> Unit,
) {
return addTag(earlierVersion, "p", pubKeyHex, isPrivate, signer, createdAt, onReady)
}
) = addTag(earlierVersion, "p", pubKeyHex, isPrivate, signer, createdAt, onReady)
fun addTag(
earlierVersion: PeopleListEvent,
@@ -284,9 +273,7 @@ class PeopleListEvent(
signer: NostrSigner,
createdAt: Long = TimeUtils.now(),
onReady: (PeopleListEvent) -> Unit,
) {
return removeTag(earlierVersion, "word", word, isPrivate, signer, createdAt, onReady)
}
) = removeTag(earlierVersion, "word", word, isPrivate, signer, createdAt, onReady)
fun removeUser(
earlierVersion: PeopleListEvent,
@@ -295,9 +282,7 @@ class PeopleListEvent(
signer: NostrSigner,
createdAt: Long = TimeUtils.now(),
onReady: (PeopleListEvent) -> Unit,
) {
return removeTag(earlierVersion, "p", pubKeyHex, isPrivate, signer, createdAt, onReady)
}
) = removeTag(earlierVersion, "p", pubKeyHex, isPrivate, signer, createdAt, onReady)
fun removeTag(
earlierVersion: PeopleListEvent,