Move to a cache model where we defer the event's verification until the last moment before adding to cache
This commit is contained in:
+1
-1
@@ -126,7 +126,7 @@ class ThreadDualAxisChartAssemblerTest {
|
||||
var counter = 0
|
||||
eventArray.forEach {
|
||||
TestCase.assertTrue("${it.id} failed signature check", it.verify())
|
||||
LocalCache.verifyAndConsume(it, null)
|
||||
LocalCache.justConsume(it, null)
|
||||
counter++
|
||||
}
|
||||
|
||||
|
||||
@@ -2000,10 +2000,10 @@ class Account(
|
||||
if (!isWriteable()) return null
|
||||
|
||||
Amethyst.instance.client.send(data, relayList = relayList)
|
||||
LocalCache.consume(data, null)
|
||||
LocalCache.justConsume(data, null)
|
||||
|
||||
Amethyst.instance.client.send(signedEvent, relayList = relayList)
|
||||
LocalCache.consume(signedEvent, null)
|
||||
LocalCache.justConsume(signedEvent, null)
|
||||
|
||||
return LocalCache.getNoteIfExists(signedEvent.id)
|
||||
}
|
||||
@@ -2012,8 +2012,8 @@ class Account(
|
||||
data: FileStorageEvent,
|
||||
signedEvent: FileStorageHeaderEvent,
|
||||
): Note? {
|
||||
LocalCache.consume(data, null)
|
||||
LocalCache.consume(signedEvent, null)
|
||||
LocalCache.justConsume(data, null)
|
||||
LocalCache.justConsume(signedEvent, null)
|
||||
|
||||
return LocalCache.getNoteIfExists(signedEvent.id)
|
||||
}
|
||||
@@ -2695,7 +2695,7 @@ class Account(
|
||||
LocalCache.justConsume(gift, null)
|
||||
}
|
||||
|
||||
LocalCache.consume(giftWrap, null)
|
||||
LocalCache.justConsume(giftWrap, null)
|
||||
}
|
||||
|
||||
val id = mine.firstOrNull()?.id
|
||||
@@ -2839,7 +2839,7 @@ class Account(
|
||||
},
|
||||
) {
|
||||
Amethyst.instance.client.send(it)
|
||||
LocalCache.consume(it, null)
|
||||
LocalCache.justConsume(it, null)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2996,7 +2996,7 @@ class Account(
|
||||
signer = signer,
|
||||
) {
|
||||
Amethyst.instance.client.send(it)
|
||||
LocalCache.consume(it, null)
|
||||
LocalCache.justConsume(it, null)
|
||||
}
|
||||
} else {
|
||||
MuteListEvent.createListWithWord(
|
||||
@@ -3005,7 +3005,7 @@ class Account(
|
||||
signer = signer,
|
||||
) {
|
||||
Amethyst.instance.client.send(it)
|
||||
LocalCache.consume(it, null)
|
||||
LocalCache.justConsume(it, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3020,7 +3020,7 @@ class Account(
|
||||
signer = signer,
|
||||
) {
|
||||
Amethyst.instance.client.send(it)
|
||||
LocalCache.consume(it, null)
|
||||
LocalCache.justConsume(it, null)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3033,7 +3033,7 @@ class Account(
|
||||
signer = signer,
|
||||
) {
|
||||
Amethyst.instance.client.send(it)
|
||||
LocalCache.consume(it, null)
|
||||
LocalCache.justConsume(it, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3049,7 +3049,7 @@ class Account(
|
||||
signer = signer,
|
||||
) {
|
||||
Amethyst.instance.client.send(it)
|
||||
LocalCache.consume(it, null)
|
||||
LocalCache.justConsume(it, null)
|
||||
}
|
||||
} else {
|
||||
MuteListEvent.createListWithUser(
|
||||
@@ -3058,7 +3058,7 @@ class Account(
|
||||
signer = signer,
|
||||
) {
|
||||
Amethyst.instance.client.send(it)
|
||||
LocalCache.consume(it, null)
|
||||
LocalCache.justConsume(it, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3073,7 +3073,7 @@ class Account(
|
||||
signer = signer,
|
||||
) {
|
||||
Amethyst.instance.client.send(it)
|
||||
LocalCache.consume(it, null)
|
||||
LocalCache.justConsume(it, null)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3086,7 +3086,7 @@ class Account(
|
||||
signer = signer,
|
||||
) {
|
||||
Amethyst.instance.client.send(it)
|
||||
LocalCache.consume(it, null)
|
||||
LocalCache.justConsume(it, null)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3709,25 +3709,25 @@ class Account(
|
||||
Log.d("AccountRegisterObservers", "Loading saved user metadata ${it.toJson()}")
|
||||
|
||||
@OptIn(DelicateCoroutinesApi::class)
|
||||
GlobalScope.launch(Dispatchers.IO) { LocalCache.consume(it, null) }
|
||||
GlobalScope.launch(Dispatchers.IO) { LocalCache.justConsume(it, null) }
|
||||
}
|
||||
|
||||
settings.backupDMRelayList?.let {
|
||||
Log.d("AccountRegisterObservers", "Loading saved DM Relay List ${it.toJson()}")
|
||||
@OptIn(DelicateCoroutinesApi::class)
|
||||
GlobalScope.launch(Dispatchers.IO) { LocalCache.verifyAndConsume(it, null) }
|
||||
GlobalScope.launch(Dispatchers.IO) { LocalCache.justConsume(it, null) }
|
||||
}
|
||||
|
||||
settings.backupNIP65RelayList?.let {
|
||||
Log.d("AccountRegisterObservers", "Loading saved nip65 relay list ${it.toJson()}")
|
||||
@OptIn(DelicateCoroutinesApi::class)
|
||||
GlobalScope.launch(Dispatchers.IO) { LocalCache.verifyAndConsume(it, null) }
|
||||
GlobalScope.launch(Dispatchers.IO) { LocalCache.justConsume(it, null) }
|
||||
}
|
||||
|
||||
settings.backupSearchRelayList?.let {
|
||||
Log.d("AccountRegisterObservers", "Loading saved search relay list ${it.toJson()}")
|
||||
@OptIn(DelicateCoroutinesApi::class)
|
||||
GlobalScope.launch(Dispatchers.IO) { LocalCache.verifyAndConsume(it, null) }
|
||||
GlobalScope.launch(Dispatchers.IO) { LocalCache.justConsume(it, null) }
|
||||
}
|
||||
|
||||
settings.backupPrivateHomeRelayList?.let { event ->
|
||||
@@ -3735,7 +3735,7 @@ class Account(
|
||||
@OptIn(DelicateCoroutinesApi::class)
|
||||
GlobalScope.launch(Dispatchers.IO) {
|
||||
event.privateTags(signer) {
|
||||
LocalCache.verifyAndConsume(event, null)
|
||||
LocalCache.justConsume(event, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3744,7 +3744,7 @@ class Account(
|
||||
Log.d("AccountRegisterObservers", "Loading saved app specific data ${event.toJson()}")
|
||||
@OptIn(DelicateCoroutinesApi::class)
|
||||
GlobalScope.launch(Dispatchers.IO) {
|
||||
LocalCache.verifyAndConsume(event, null)
|
||||
LocalCache.justConsume(event, null)
|
||||
signer.decrypt(event.content, event.pubKey) { decrypted ->
|
||||
try {
|
||||
val syncedSettings = EventMapper.mapper.readValue<AccountSyncedSettingsInternal>(decrypted)
|
||||
@@ -3759,22 +3759,34 @@ class Account(
|
||||
}
|
||||
}
|
||||
|
||||
settings.backupMuteList?.let {
|
||||
Log.d("AccountRegisterObservers", "Loading saved mute list ${it.toJson()}")
|
||||
settings.backupMuteList?.let { event ->
|
||||
Log.d("AccountRegisterObservers", "Loading saved mute list ${event.toJson()}")
|
||||
@OptIn(DelicateCoroutinesApi::class)
|
||||
GlobalScope.launch(Dispatchers.IO) { LocalCache.verifyAndConsume(it, null) }
|
||||
GlobalScope.launch(Dispatchers.IO) {
|
||||
event.privateTags(signer) {
|
||||
LocalCache.justConsume(event, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
settings.backupEphemeralChatList?.let {
|
||||
Log.d("AccountRegisterObservers", "Loading saved ephemeral chat list ${it.toJson()}")
|
||||
settings.backupEphemeralChatList?.let { event ->
|
||||
Log.d("AccountRegisterObservers", "Loading saved ephemeral chat list ${event.toJson()}")
|
||||
@OptIn(DelicateCoroutinesApi::class)
|
||||
GlobalScope.launch(Dispatchers.IO) { LocalCache.verifyAndConsume(it, null) }
|
||||
GlobalScope.launch(Dispatchers.IO) {
|
||||
event.privateTags(signer) {
|
||||
LocalCache.justConsume(event, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
settings.backupChannelList?.let {
|
||||
Log.d("AccountRegisterObservers", "Loading saved channel list ${it.toJson()}")
|
||||
settings.backupChannelList?.let { event ->
|
||||
Log.d("AccountRegisterObservers", "Loading saved channel list ${event.toJson()}")
|
||||
@OptIn(DelicateCoroutinesApi::class)
|
||||
GlobalScope.launch(Dispatchers.IO) { LocalCache.verifyAndConsume(it, null) }
|
||||
GlobalScope.launch(Dispatchers.IO) {
|
||||
event.privateTags(signer) {
|
||||
LocalCache.justConsume(event, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// saves contact list for the next time.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -29,7 +29,6 @@ import com.vitorpamplona.amethyst.service.replace
|
||||
import com.vitorpamplona.amethyst.tryAndWait
|
||||
import com.vitorpamplona.amethyst.ui.note.toShortenHex
|
||||
import com.vitorpamplona.ammolite.relays.BundledUpdate
|
||||
import com.vitorpamplona.ammolite.relays.Relay
|
||||
import com.vitorpamplona.ammolite.relays.RelayBriefInfoCache
|
||||
import com.vitorpamplona.ammolite.relays.filters.EOSETime
|
||||
import com.vitorpamplona.quartz.experimental.bounties.addedRewardValue
|
||||
@@ -448,7 +447,7 @@ open class Note(
|
||||
}
|
||||
}
|
||||
|
||||
fun hasRelay(relay: Relay) = relay.brief !in relays
|
||||
fun hasRelay(relay: RelayBriefInfoCache.RelayBriefInfo) = relay !in relays
|
||||
|
||||
fun addRelay(brief: RelayBriefInfoCache.RelayBriefInfo) {
|
||||
if (brief !in relays) {
|
||||
|
||||
+14
-15
@@ -62,7 +62,6 @@ class EventNotificationConsumer(
|
||||
|
||||
suspend fun consume(event: GiftWrapEvent) {
|
||||
Log.d(TAG, "New Notification Arrived")
|
||||
if (!LocalCache.justVerify(event)) return
|
||||
|
||||
// PushNotification Wraps don't include a receiver.
|
||||
// Test with all logged in accounts
|
||||
@@ -108,9 +107,8 @@ class EventNotificationConsumer(
|
||||
account: AccountSettings,
|
||||
) {
|
||||
val consumed = LocalCache.hasConsumed(notificationEvent)
|
||||
val verified = LocalCache.justVerify(notificationEvent)
|
||||
Log.d(TAG, "New Notification ${notificationEvent.kind} ${notificationEvent.id} Arrived for ${signer.pubKey} consumed= $consumed && verified= $verified")
|
||||
if (!consumed && verified) {
|
||||
Log.d(TAG, "New Notification ${notificationEvent.kind} ${notificationEvent.id} Arrived for ${signer.pubKey} consumed= $consumed")
|
||||
if (!consumed) {
|
||||
Log.d(TAG, "New Notification was verified")
|
||||
unwrapAndConsume(notificationEvent, signer) { innerEvent ->
|
||||
if (!notificationManager().areNotificationsEnabled()) return@unwrapAndConsume
|
||||
@@ -135,8 +133,6 @@ class EventNotificationConsumer(
|
||||
|
||||
suspend fun findAccountAndConsume(event: Event) {
|
||||
Log.d(TAG, "New Notification Arrived")
|
||||
if (!LocalCache.justVerify(event)) return
|
||||
|
||||
val users = event.taggedUserIds().map { LocalCache.getOrCreateUser(it) }
|
||||
val npubs = users.map { it.pubkeyNpub() }.toSet()
|
||||
|
||||
@@ -174,24 +170,27 @@ class EventNotificationConsumer(
|
||||
signer: NostrSigner,
|
||||
onReady: (Event) -> Unit,
|
||||
) {
|
||||
if (!LocalCache.justVerify(event)) return
|
||||
if (LocalCache.hasConsumed(event)) return
|
||||
|
||||
when (event) {
|
||||
is GiftWrapEvent -> {
|
||||
event.unwrap(signer) {
|
||||
unwrapAndConsume(it, signer, onReady)
|
||||
LocalCache.justConsume(event, null)
|
||||
if (LocalCache.justConsume(event, null)) {
|
||||
// new event
|
||||
event.unwrap(signer) {
|
||||
unwrapAndConsume(it, signer, onReady)
|
||||
}
|
||||
}
|
||||
}
|
||||
is SealedRumorEvent -> {
|
||||
event.unseal(signer) {
|
||||
if (!LocalCache.hasConsumed(it)) {
|
||||
if (LocalCache.justConsume(event, null)) {
|
||||
// new event
|
||||
event.unseal(signer) {
|
||||
// this is not verifiable
|
||||
LocalCache.justConsume(it, null)
|
||||
onReady(it)
|
||||
if (!LocalCache.hasConsumed(it)) {
|
||||
LocalCache.justConsume(it, null)
|
||||
onReady(it)
|
||||
}
|
||||
}
|
||||
LocalCache.justConsume(event, null)
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ class CacheClientConnector(
|
||||
) {
|
||||
val receiver =
|
||||
EventCollector(client) { event, relay ->
|
||||
cache.verifyAndConsume(event, relay)
|
||||
cache.justConsume(event, relay)
|
||||
}
|
||||
|
||||
val confirmationWatcher =
|
||||
|
||||
+1
-1
@@ -155,7 +155,7 @@ class SearchFilterAssembler(
|
||||
is Note -> filterByEvent(parsed.hex)
|
||||
is NEvent -> filterByEvent(parsed.hex)
|
||||
is NEmbed -> {
|
||||
cache.verifyAndConsume(parsed.event, null)
|
||||
cache.justConsume(parsed.event, null)
|
||||
emptyList()
|
||||
}
|
||||
|
||||
|
||||
@@ -183,7 +183,7 @@ fun uriToRoute(uri: String?): Route? =
|
||||
|
||||
is NEmbed -> {
|
||||
if (LocalCache.getNoteIfExists(nip19.event.id) == null) {
|
||||
LocalCache.verifyAndConsume(nip19.event, null)
|
||||
LocalCache.justConsume(nip19.event, null)
|
||||
}
|
||||
Route.EventRedirect(nip19.event.id)
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@ fun PollNotePreview() {
|
||||
withContext(Dispatchers.IO) {
|
||||
LocalCache.justConsume(event, null)
|
||||
LocalCache.consume(zapVote.zapRequest!!)
|
||||
LocalCache.consume(zapVote, null)
|
||||
LocalCache.justConsume(zapVote, null)
|
||||
baseNote = LocalCache.getOrCreateNote("6ff9bc13d27490f6e3953325260bd996901a143de89886a0608c39e7d0160a72")
|
||||
}
|
||||
}
|
||||
|
||||
+14
-10
@@ -1091,7 +1091,7 @@ class AccountViewModel(
|
||||
var note = checkGetOrCreateNote(event.id)
|
||||
|
||||
if (note == null) {
|
||||
LocalCache.verifyAndConsume(event, null)
|
||||
LocalCache.justConsume(event, null)
|
||||
note = checkGetOrCreateNote(event.id)
|
||||
}
|
||||
|
||||
@@ -1471,8 +1471,9 @@ class AccountViewModel(
|
||||
unwrapIfNeeded(existingNote.event, onReady)
|
||||
} else {
|
||||
event.unwrap(account.signer) {
|
||||
LocalCache.verifyAndConsume(it, null)
|
||||
unwrapIfNeeded(it, onReady)
|
||||
if (LocalCache.justConsume(it, null)) {
|
||||
unwrapIfNeeded(it, onReady)
|
||||
}
|
||||
}
|
||||
}
|
||||
} ?: run {
|
||||
@@ -1481,8 +1482,9 @@ class AccountViewModel(
|
||||
if (existingNote != null) {
|
||||
unwrapIfNeeded(existingNote.event, onReady)
|
||||
} else {
|
||||
LocalCache.verifyAndConsume(it, null)
|
||||
unwrapIfNeeded(it, onReady)
|
||||
if (LocalCache.justConsume(it, null)) {
|
||||
unwrapIfNeeded(it, onReady)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1495,8 +1497,9 @@ class AccountViewModel(
|
||||
} else {
|
||||
event.unseal(account.signer) {
|
||||
// this is not verifiable
|
||||
LocalCache.justConsume(it, null)
|
||||
unwrapIfNeeded(it, onReady)
|
||||
if (LocalCache.justConsume(it, null)) {
|
||||
unwrapIfNeeded(it, onReady)
|
||||
}
|
||||
}
|
||||
}
|
||||
} ?: run {
|
||||
@@ -1506,8 +1509,9 @@ class AccountViewModel(
|
||||
unwrapIfNeeded(existingNote.event, onReady)
|
||||
} else {
|
||||
// this is not verifiable
|
||||
LocalCache.justConsume(it, null)
|
||||
unwrapIfNeeded(it, onReady)
|
||||
if (LocalCache.justConsume(it, null)) {
|
||||
unwrapIfNeeded(it, onReady)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1755,7 +1759,7 @@ class AccountViewModel(
|
||||
val baseNote = LocalCache.getOrCreateNote(parsed.event)
|
||||
if (baseNote.event == null) {
|
||||
launch(Dispatchers.Default) {
|
||||
LocalCache.verifyAndConsume(parsed.event, null)
|
||||
LocalCache.justConsume(parsed.event, null)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-2
@@ -78,8 +78,7 @@ class PrecacheNewNotesProcessor(
|
||||
val inner = event.innerEventId
|
||||
if (inner == null) {
|
||||
event.unwrap(account.signer) {
|
||||
if (cache.justVerify(it)) {
|
||||
cache.justConsume(it, null)
|
||||
if (cache.justConsume(it, null)) {
|
||||
cache.copyRelaysFromTo(note, it)
|
||||
consumeAlreadyVerified(it, note)
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ package com.vitorpamplona.quartz.nip09Deletions
|
||||
import com.vitorpamplona.quartz.nip01Core.core.AddressableEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.verify
|
||||
import com.vitorpamplona.quartz.utils.LargeCache
|
||||
|
||||
class DeletionIndex {
|
||||
@@ -45,14 +46,24 @@ class DeletionIndex {
|
||||
// Anything newer than the date should not be deleted.
|
||||
private val deletedReferencesBefore = LargeCache<DeletionRequest, DeletionEvent>()
|
||||
|
||||
fun add(event: DeletionEvent): Boolean {
|
||||
fun add(
|
||||
event: DeletionEvent,
|
||||
wasVerified: Boolean,
|
||||
): Boolean {
|
||||
var atLeastOne = false
|
||||
var myWasVerified = wasVerified
|
||||
|
||||
event.tags.forEach {
|
||||
if (it.size > 1 && (it[0] == "a" || it[0] == "e")) {
|
||||
if (add(it[1], event.pubKey, event)) {
|
||||
atLeastOne = true
|
||||
}
|
||||
event.deleteEventIds().forEach { toDelete ->
|
||||
if (add(toDelete, event.pubKey, event, myWasVerified)) {
|
||||
myWasVerified = true
|
||||
atLeastOne = true
|
||||
}
|
||||
}
|
||||
|
||||
event.deleteAddressIds().forEach { toDelete ->
|
||||
if (add(toDelete, event.pubKey, event, myWasVerified)) {
|
||||
myWasVerified = true
|
||||
atLeastOne = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,13 +74,16 @@ class DeletionIndex {
|
||||
ref: String,
|
||||
byPubKey: HexKey,
|
||||
deletionEvent: DeletionEvent,
|
||||
wasVerified: Boolean,
|
||||
): Boolean {
|
||||
val key = DeletionRequest(ref, byPubKey)
|
||||
val previousDeletionEvent = deletedReferencesBefore.get(key)
|
||||
|
||||
if (previousDeletionEvent == null || deletionEvent.createdAt > previousDeletionEvent.createdAt) {
|
||||
deletedReferencesBefore.put(key, deletionEvent)
|
||||
return true
|
||||
if (wasVerified || deletionEvent.verify()) {
|
||||
deletedReferencesBefore.put(key, deletionEvent)
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user