From 8a59904bfce050d1f6019a2731701df11cba04f0 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Fri, 16 May 2025 19:27:39 -0400 Subject: [PATCH] Fixes local cache strategy to create an option and not verify events from Seals. --- .../ThreadDualAxisChartAssemblerTest.kt | 2 +- .../vitorpamplona/amethyst/model/Account.kt | 166 ++-- .../amethyst/model/LocalCache.kt | 740 ++++++++++-------- .../EventNotificationConsumer.kt | 9 +- .../relayClient/CacheClientConnector.kt | 2 +- .../SearchWatcherSubAssembler.kt | 2 +- .../vitorpamplona/amethyst/ui/MainActivity.kt | 2 +- .../markdown/RenderContentAsMarkdown.kt | 4 +- .../amethyst/ui/note/PollNote.kt | 8 +- .../ui/note/elements/ZapTheDevsCard.kt | 2 +- .../amethyst/ui/note/types/LiveActivity.kt | 2 +- .../amethyst/ui/note/types/Torrent.kt | 2 +- .../amethyst/ui/note/types/TorrentComment.kt | 4 +- .../ui/screen/loggedIn/AccountViewModel.kt | 14 +- .../loggedIn/PrecacheNewNotesProcessor.kt | 10 +- .../loggedIn/threadview/ThreadFeedView.kt | 2 +- 16 files changed, 549 insertions(+), 422 deletions(-) diff --git a/amethyst/src/androidTest/java/com/vitorpamplona/amethyst/ThreadDualAxisChartAssemblerTest.kt b/amethyst/src/androidTest/java/com/vitorpamplona/amethyst/ThreadDualAxisChartAssemblerTest.kt index ebbda80f9..61497dfb1 100644 --- a/amethyst/src/androidTest/java/com/vitorpamplona/amethyst/ThreadDualAxisChartAssemblerTest.kt +++ b/amethyst/src/androidTest/java/com/vitorpamplona/amethyst/ThreadDualAxisChartAssemblerTest.kt @@ -126,7 +126,7 @@ class ThreadDualAxisChartAssemblerTest { var counter = 0 eventArray.forEach { TestCase.assertTrue("${it.id} failed signature check", it.verify()) - LocalCache.justConsume(it, null) + LocalCache.justConsume(it, null, false) counter++ } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt index 5421adff5..9d2102876 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt @@ -1227,7 +1227,7 @@ class Account( signer = signer, ) { Amethyst.instance.client.send(it) - LocalCache.justConsume(it, null) + LocalCache.justConsumeMyOwnEvent(it) } } } @@ -1244,7 +1244,7 @@ class Account( signer = signer, ) { Amethyst.instance.client.send(it) - LocalCache.justConsume(it, null) + LocalCache.justConsumeMyOwnEvent(it) } } else { ContactListEvent.createFromScratch( @@ -1257,7 +1257,7 @@ class Account( ) { // Keep this local to avoid erasing a good contact list. // Amethyst.instance.client.send(it) - LocalCache.justConsume(it, null) + LocalCache.justConsumeMyOwnEvent(it) } } } @@ -1322,7 +1322,7 @@ class Account( signer.sign(template) { Amethyst.instance.client.send(it) - LocalCache.justConsume(it, null) + LocalCache.justConsumeMyOwnEvent(it) } } @@ -1393,7 +1393,7 @@ class Account( ReactionEvent.build(emojiUrl, EventHintBundle(it, note.relayHintUrl())), ) { Amethyst.instance.client.send(it) - LocalCache.consume(it) + LocalCache.justConsumeMyOwnEvent(it) } } @@ -1406,7 +1406,7 @@ class Account( ReactionEvent.build(reaction, it), ) { Amethyst.instance.client.send(it) - LocalCache.consume(it) + LocalCache.justConsumeMyOwnEvent(it) } } } @@ -1510,7 +1510,7 @@ class Account( Amethyst.instance.sources.nwc .subscribe(filter) - LocalCache.consume(event, zappedNote) { it.response(signer) { onResponse(it) } } + LocalCache.consume(event, zappedNote, true) { it.response(signer) { onResponse(it) } } Amethyst.instance.client.sendSingle( signedEvent = event, @@ -1569,7 +1569,7 @@ class Account( note.event?.let { signer.sign(ReportEvent.build(it, type)) { Amethyst.instance.client.send(it) - LocalCache.justConsume(it, null) + LocalCache.justConsumeMyOwnEvent(it) } } } @@ -1588,7 +1588,7 @@ class Account( val template = ReportEvent.build(user.pubkeyHex, type) signer.sign(template) { Amethyst.instance.client.send(it) - LocalCache.justConsume(it, null) + LocalCache.justConsumeMyOwnEvent(it) } } @@ -1607,7 +1607,7 @@ class Account( DeletionEvent.build(chunkedList), ) { deletionEvent -> Amethyst.instance.client.send(deletionEvent) - LocalCache.justConsume(deletionEvent, null) + LocalCache.justConsumeMyOwnEvent(deletionEvent) } } } @@ -1677,7 +1677,7 @@ class Account( signer.sign(template) { Amethyst.instance.client.send(it) - LocalCache.justConsume(it, null) + LocalCache.justConsumeMyOwnEvent(it) } } @@ -1726,7 +1726,7 @@ class Account( } signer.sign(template) { - LocalCache.justConsume(it, null) + LocalCache.justConsumeMyOwnEvent(it) Amethyst.instance.client.send(it) settings.pendingAttestations.update { @@ -1760,7 +1760,7 @@ class Account( if (contactList != null) { ContactListEvent.followUser(contactList, user.pubkeyHex, signer) { Amethyst.instance.client.send(it) - LocalCache.justConsume(it, null) + LocalCache.justConsumeMyOwnEvent(it) } } else { ContactListEvent.createFromScratch( @@ -1775,7 +1775,7 @@ class Account( signer = signer, ) { Amethyst.instance.client.send(it) - LocalCache.justConsume(it, null) + LocalCache.justConsumeMyOwnEvent(it) } } } @@ -1785,7 +1785,7 @@ class Account( publicChatList.follow(channel) { sendToPrivateOutboxAndLocal(it) - LocalCache.justConsume(it, null) + LocalCache.justConsumeMyOwnEvent(it) } } @@ -1794,7 +1794,7 @@ class Account( publicChatList.unfollow(channel) { sendToPrivateOutboxAndLocal(it) - LocalCache.justConsume(it, null) + LocalCache.justConsumeMyOwnEvent(it) } } @@ -1803,7 +1803,7 @@ class Account( ephemeralChatList.follow(channel) { sendToPrivateOutboxAndLocal(it) - LocalCache.justConsumeInner(it, RelayBriefInfoCache.get(channel.roomId.relayUrl)) + LocalCache.justConsumeInner(it, RelayBriefInfoCache.get(channel.roomId.relayUrl), true) } } @@ -1812,7 +1812,7 @@ class Account( ephemeralChatList.unfollow(channel) { sendToPrivateOutboxAndLocal(it) - LocalCache.justConsumeInner(it, RelayBriefInfoCache.get(channel.roomId.relayUrl)) + LocalCache.justConsumeInner(it, RelayBriefInfoCache.get(channel.roomId.relayUrl), true) } } @@ -1824,7 +1824,7 @@ class Account( if (contactList != null) { ContactListEvent.followAddressableEvent(contactList, community.toATag(), signer) { Amethyst.instance.client.send(it) - LocalCache.justConsume(it, null) + LocalCache.justConsumeMyOwnEvent(it) } } else { val relays = @@ -1840,7 +1840,7 @@ class Account( signer = signer, ) { Amethyst.instance.client.send(it) - LocalCache.justConsume(it, null) + LocalCache.justConsumeMyOwnEvent(it) } } } @@ -1857,7 +1857,7 @@ class Account( signer, ) { Amethyst.instance.client.send(it) - LocalCache.justConsume(it, null) + LocalCache.justConsumeMyOwnEvent(it) } } else { ContactListEvent.createFromScratch( @@ -1872,7 +1872,7 @@ class Account( signer = signer, ) { Amethyst.instance.client.send(it) - LocalCache.justConsume(it, null) + LocalCache.justConsumeMyOwnEvent(it) } } } @@ -1907,7 +1907,7 @@ class Account( fun onNewEventCreated(event: Event) { Amethyst.instance.client.send(event) - LocalCache.justConsume(event, null) + LocalCache.justConsumeMyOwnEvent(event) } fun unfollow(user: User) { @@ -2008,10 +2008,10 @@ class Account( if (!isWriteable()) return null Amethyst.instance.client.send(data, relayList = relayList) - LocalCache.justConsume(data, null) + LocalCache.justConsumeMyOwnEvent(data) Amethyst.instance.client.send(signedEvent, relayList = relayList) - LocalCache.justConsume(signedEvent, null) + LocalCache.justConsumeMyOwnEvent(signedEvent) return LocalCache.getNoteIfExists(signedEvent.id) } @@ -2020,8 +2020,8 @@ class Account( data: FileStorageEvent, signedEvent: FileStorageHeaderEvent, ): Note? { - LocalCache.justConsume(data, null) - LocalCache.justConsume(signedEvent, null) + LocalCache.justConsumeMyOwnEvent(data) + LocalCache.justConsumeMyOwnEvent(signedEvent) return LocalCache.getNoteIfExists(signedEvent.id) } @@ -2062,7 +2062,7 @@ class Account( onReady: (Note) -> Unit, ) { Amethyst.instance.client.send(signedEvent, relayList = relayList) - LocalCache.justConsume(signedEvent, null) + LocalCache.justConsumeMyOwnEvent(signedEvent) LocalCache.getNoteIfExists(signedEvent.id)?.let { onReady(it) } } @@ -2233,7 +2233,7 @@ class Account( } } else { signer.sign(template) { - LocalCache.justConsume(it, null) + LocalCache.justConsumeMyOwnEvent(it) Amethyst.instance.client.send(it) } } @@ -2245,7 +2245,7 @@ class Account( onDone: (T) -> Unit = {}, ) { signer.sign(template) { - LocalCache.justConsume(it, null) + LocalCache.justConsumeMyOwnEvent(it) Amethyst.instance.client.sendPrivately(it, relayList = convertRelayList(relayList)) onDone(it) } @@ -2257,7 +2257,7 @@ class Account( onDone: (T) -> Unit = {}, ) { signer.sign(template) { - LocalCache.justConsume(it, null) + LocalCache.justConsumeMyOwnEvent(it) val relays = relayList(it) if (relays != null) { Amethyst.instance.client.sendPrivately(it, relayList = convertRelayList(relays)) @@ -2274,7 +2274,7 @@ class Account( broadcastNotes: Set, ) { signer.sign(template) { - LocalCache.justConsume(it, null) + LocalCache.justConsumeMyOwnEvent(it) Amethyst.instance.client.send(it, relayList = relayList) broadcastNotes.forEach { it.event?.let { Amethyst.instance.client.send(it, relayList = relayList) } } @@ -2302,7 +2302,7 @@ class Account( } } else { signer.sign(template) { - LocalCache.justConsume(it, null) + LocalCache.justConsumeMyOwnEvent(it) Amethyst.instance.client.send(it, relayList = relayList) broadcastNotes.forEach { it.event?.let { Amethyst.instance.client.send(it, relayList = relayList) } } @@ -2336,7 +2336,7 @@ class Account( ) } - LocalCache.justConsume(it, null) + LocalCache.justConsumeMyOwnEvent(it) Amethyst.instance.client.sendPrivately(it, relayList = connect) broadcastNotes.forEach { it.event?.let { Amethyst.instance.client.sendPrivately(it, relayList = connect) } } } @@ -2382,7 +2382,7 @@ class Account( ) }, ) - LocalCache.justConsume(it, null) + LocalCache.justConsumeMyOwnEvent(it) } } delete(note) @@ -2557,7 +2557,7 @@ class Account( summary = summary, signer = signer, ) { - LocalCache.justConsume(it, null) + LocalCache.justConsumeMyOwnEvent(it) Amethyst.instance.client.send(it, relayList = relayList) } } @@ -2674,7 +2674,7 @@ class Account( } else { Amethyst.instance.client.send(event) } - LocalCache.justConsume(event, null) + LocalCache.justConsumeMyOwnEvent(event) } fun convertRelayList(broadcast: List): List = @@ -2696,14 +2696,14 @@ class Account( giftWrap.unwrap(signer) { gift -> if (gift is SealedRumorEvent) { gift.unseal(signer) { rumor -> - LocalCache.justConsume(rumor, null) + LocalCache.justConsumeMyOwnEvent(rumor) } } - LocalCache.justConsume(gift, null) + LocalCache.justConsumeMyOwnEvent(gift) } - LocalCache.justConsume(giftWrap, null) + LocalCache.justConsumeMyOwnEvent(giftWrap) } val id = mine.firstOrNull()?.id @@ -2753,7 +2753,7 @@ class Account( StatusEvent.update(oldEvent, newStatus, signer) { Amethyst.instance.client.send(it) - LocalCache.justConsume(it, null) + LocalCache.justConsumeMyOwnEvent(it) } } @@ -2762,7 +2762,7 @@ class Account( StatusEvent.create(newStatus, "general", expiration = null, signer) { Amethyst.instance.client.send(it) - LocalCache.justConsume(it, null) + LocalCache.justConsumeMyOwnEvent(it) } } @@ -2772,13 +2772,13 @@ class Account( StatusEvent.clear(oldEvent, signer) { event -> Amethyst.instance.client.send(event) - LocalCache.justConsume(event, null) + LocalCache.justConsumeMyOwnEvent(event) signer.sign( DeletionEvent.buildForVersionOnly(listOf(event)), ) { event2 -> Amethyst.instance.client.send(event2) - LocalCache.justConsume(event2, null) + LocalCache.justConsumeMyOwnEvent(event2) } } } @@ -2796,7 +2796,7 @@ class Account( signer.sign(EmojiPackSelectionEvent.remove(noteEvent, emojiPackEvent)) { Amethyst.instance.client.send(it) - LocalCache.justConsume(it, null) + LocalCache.justConsumeMyOwnEvent(it) } } @@ -2813,7 +2813,7 @@ class Account( if (usersEmojiList.event == null) { signer.sign(EmojiPackSelectionEvent.build(listOf(eventHint))) { Amethyst.instance.client.send(it) - LocalCache.justConsume(it, null) + LocalCache.justConsumeMyOwnEvent(it) } } else { val noteEvent = usersEmojiList.event @@ -2821,7 +2821,7 @@ class Account( signer.sign(EmojiPackSelectionEvent.add(noteEvent, eventHint)) { Amethyst.instance.client.send(it) - LocalCache.justConsume(it, null) + LocalCache.justConsumeMyOwnEvent(it) } } } @@ -2847,7 +2847,7 @@ class Account( }, ) { Amethyst.instance.client.send(it) - LocalCache.justConsume(it, null) + LocalCache.justConsumeMyOwnEvent(it) } } @@ -2870,7 +2870,7 @@ class Account( signer, ) { Amethyst.instance.client.send(it) - LocalCache.consume(it) + LocalCache.justConsumeMyOwnEvent(it) } } else { BookmarkListEvent.addEvent( @@ -2880,7 +2880,7 @@ class Account( signer, ) { Amethyst.instance.client.send(it) - LocalCache.consume(it) + LocalCache.justConsumeMyOwnEvent(it) } } } @@ -2901,7 +2901,7 @@ class Account( signer, ) { Amethyst.instance.client.send(it) - LocalCache.consume(it) + LocalCache.justConsumeMyOwnEvent(it) } } else { BookmarkListEvent.removeEvent( @@ -2911,7 +2911,7 @@ class Account( signer, ) { Amethyst.instance.client.send(it) - LocalCache.consume(it) + LocalCache.justConsumeMyOwnEvent(it) } } } @@ -3004,7 +3004,7 @@ class Account( signer = signer, ) { Amethyst.instance.client.send(it) - LocalCache.justConsume(it, null) + LocalCache.justConsumeMyOwnEvent(it) } } else { MuteListEvent.createListWithWord( @@ -3013,7 +3013,7 @@ class Account( signer = signer, ) { Amethyst.instance.client.send(it) - LocalCache.justConsume(it, null) + LocalCache.justConsumeMyOwnEvent(it) } } } @@ -3028,7 +3028,7 @@ class Account( signer = signer, ) { Amethyst.instance.client.send(it) - LocalCache.justConsume(it, null) + LocalCache.justConsumeMyOwnEvent(it) } } @@ -3041,7 +3041,7 @@ class Account( signer = signer, ) { Amethyst.instance.client.send(it) - LocalCache.justConsume(it, null) + LocalCache.justConsumeMyOwnEvent(it) } } } @@ -3057,7 +3057,7 @@ class Account( signer = signer, ) { Amethyst.instance.client.send(it) - LocalCache.justConsume(it, null) + LocalCache.justConsumeMyOwnEvent(it) } } else { MuteListEvent.createListWithUser( @@ -3066,7 +3066,7 @@ class Account( signer = signer, ) { Amethyst.instance.client.send(it) - LocalCache.justConsume(it, null) + LocalCache.justConsumeMyOwnEvent(it) } } } @@ -3081,7 +3081,7 @@ class Account( signer = signer, ) { Amethyst.instance.client.send(it) - LocalCache.justConsume(it, null) + LocalCache.justConsumeMyOwnEvent(it) } } @@ -3094,7 +3094,7 @@ class Account( signer = signer, ) { Amethyst.instance.client.send(it) - LocalCache.justConsume(it, null) + LocalCache.justConsumeMyOwnEvent(it) } } @@ -3130,7 +3130,7 @@ class Account( } else { Amethyst.instance.client.send(it) } - LocalCache.justConsume(it, null) + LocalCache.justConsumeMyOwnEvent(it) onReady(it) } } @@ -3347,7 +3347,7 @@ class Account( signer = signer, ) { Amethyst.instance.client.send(it) - LocalCache.justConsume(it, null) + LocalCache.justConsumeMyOwnEvent(it) } } else { ChatMessageRelayListEvent.createFromScratch( @@ -3355,7 +3355,7 @@ class Account( signer = signer, ) { Amethyst.instance.client.send(it) - LocalCache.justConsume(it, null) + LocalCache.justConsumeMyOwnEvent(it) } } } @@ -3381,7 +3381,7 @@ class Account( signer = signer, ) { Amethyst.instance.client.send(it) - LocalCache.justConsume(it, null) + LocalCache.justConsumeMyOwnEvent(it) } } else { PrivateOutboxRelayListEvent.createFromScratch( @@ -3389,7 +3389,7 @@ class Account( signer = signer, ) { Amethyst.instance.client.send(it) - LocalCache.justConsume(it, null) + LocalCache.justConsumeMyOwnEvent(it) } } } @@ -3415,7 +3415,7 @@ class Account( signer = signer, ) { Amethyst.instance.client.send(it) - LocalCache.justConsume(it, null) + LocalCache.justConsumeMyOwnEvent(it) } } else { SearchRelayListEvent.createFromScratch( @@ -3423,7 +3423,7 @@ class Account( signer = signer, ) { Amethyst.instance.client.send(it) - LocalCache.justConsume(it, null) + LocalCache.justConsumeMyOwnEvent(it) } } } @@ -3449,7 +3449,7 @@ class Account( signer = signer, ) { Amethyst.instance.client.send(it) - LocalCache.justConsume(it, null) + LocalCache.justConsumeMyOwnEvent(it) } } else { AdvertisedRelayListEvent.createFromScratch( @@ -3457,7 +3457,7 @@ class Account( signer = signer, ) { Amethyst.instance.client.send(it) - LocalCache.justConsume(it, null) + LocalCache.justConsumeMyOwnEvent(it) } } } @@ -3507,7 +3507,7 @@ class Account( signer.sign(template) { Amethyst.instance.client.send(it) - LocalCache.justConsume(it, null) + LocalCache.justConsumeMyOwnEvent(it) } } @@ -3523,7 +3523,7 @@ class Account( signer = signer, ) { Amethyst.instance.client.send(it) - LocalCache.justConsume(it, null) + LocalCache.justConsumeMyOwnEvent(it) } } else { BlossomServersEvent.createFromScratch( @@ -3531,7 +3531,7 @@ class Account( signer = signer, ) { Amethyst.instance.client.send(it) - LocalCache.justConsume(it, null) + LocalCache.justConsumeMyOwnEvent(it) } } } @@ -3710,32 +3710,32 @@ class Account( Log.d("AccountRegisterObservers", "Loading saved contacts ${it.toJson()}") @OptIn(DelicateCoroutinesApi::class) - GlobalScope.launch(Dispatchers.IO) { LocalCache.consume(it) } + GlobalScope.launch(Dispatchers.IO) { LocalCache.justConsumeMyOwnEvent(it) } } settings.backupUserMetadata?.let { Log.d("AccountRegisterObservers", "Loading saved user metadata ${it.toJson()}") @OptIn(DelicateCoroutinesApi::class) - GlobalScope.launch(Dispatchers.IO) { LocalCache.justConsume(it, null) } + GlobalScope.launch(Dispatchers.IO) { LocalCache.justConsumeMyOwnEvent(it) } } settings.backupDMRelayList?.let { Log.d("AccountRegisterObservers", "Loading saved DM Relay List ${it.toJson()}") @OptIn(DelicateCoroutinesApi::class) - GlobalScope.launch(Dispatchers.IO) { LocalCache.justConsume(it, null) } + GlobalScope.launch(Dispatchers.IO) { LocalCache.justConsumeMyOwnEvent(it) } } settings.backupNIP65RelayList?.let { Log.d("AccountRegisterObservers", "Loading saved nip65 relay list ${it.toJson()}") @OptIn(DelicateCoroutinesApi::class) - GlobalScope.launch(Dispatchers.IO) { LocalCache.justConsume(it, null) } + GlobalScope.launch(Dispatchers.IO) { LocalCache.justConsumeMyOwnEvent(it) } } settings.backupSearchRelayList?.let { Log.d("AccountRegisterObservers", "Loading saved search relay list ${it.toJson()}") @OptIn(DelicateCoroutinesApi::class) - GlobalScope.launch(Dispatchers.IO) { LocalCache.justConsume(it, null) } + GlobalScope.launch(Dispatchers.IO) { LocalCache.justConsumeMyOwnEvent(it) } } settings.backupPrivateHomeRelayList?.let { event -> @@ -3743,7 +3743,7 @@ class Account( @OptIn(DelicateCoroutinesApi::class) GlobalScope.launch(Dispatchers.IO) { event.privateTags(signer) { - LocalCache.justConsume(event, null) + LocalCache.justConsumeMyOwnEvent(event) } } } @@ -3752,7 +3752,7 @@ class Account( Log.d("AccountRegisterObservers", "Loading saved app specific data ${event.toJson()}") @OptIn(DelicateCoroutinesApi::class) GlobalScope.launch(Dispatchers.IO) { - LocalCache.justConsume(event, null) + LocalCache.justConsumeMyOwnEvent(event) signer.decrypt(event.content, event.pubKey) { decrypted -> try { val syncedSettings = EventMapper.mapper.readValue(decrypted) @@ -3772,7 +3772,7 @@ class Account( @OptIn(DelicateCoroutinesApi::class) GlobalScope.launch(Dispatchers.IO) { event.privateTags(signer) { - LocalCache.justConsume(event, null) + LocalCache.justConsumeMyOwnEvent(event) } } } @@ -3782,7 +3782,7 @@ class Account( @OptIn(DelicateCoroutinesApi::class) GlobalScope.launch(Dispatchers.IO) { event.privateTags(signer) { - LocalCache.justConsume(event, null) + LocalCache.justConsumeMyOwnEvent(event) } } } @@ -3792,7 +3792,7 @@ class Account( @OptIn(DelicateCoroutinesApi::class) GlobalScope.launch(Dispatchers.IO) { event.privateTags(signer) { - LocalCache.justConsume(event, null) + LocalCache.justConsumeMyOwnEvent(event) } } } @@ -3939,7 +3939,7 @@ class Account( Log.d("DB UPGRADE", "Migrating List") publicChatList.follow(oldChannels) { sendToPrivateOutboxAndLocal(it) - LocalCache.justConsume(it, null) + LocalCache.justConsumeMyOwnEvent(it) } } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt index 9beef2e5d..582502903 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt @@ -20,6 +20,7 @@ */ package com.vitorpamplona.amethyst.model +import android.R.attr.version import android.util.Log import android.util.LruCache import androidx.compose.runtime.Stable @@ -27,6 +28,7 @@ import com.vitorpamplona.amethyst.Amethyst import com.vitorpamplona.amethyst.model.observables.LatestByKindAndAuthor import com.vitorpamplona.amethyst.model.observables.LatestByKindWithETag import com.vitorpamplona.amethyst.service.checkNotInMainThread +import com.vitorpamplona.amethyst.ui.note.dateFormatter import com.vitorpamplona.ammolite.relays.BundledInsert import com.vitorpamplona.ammolite.relays.Relay import com.vitorpamplona.ammolite.relays.RelayBriefInfoCache @@ -457,6 +459,7 @@ object LocalCache : ILocalCache { fun consume( event: MetadataEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, + wasVerified: Boolean, ): Boolean { // new event val oldUser = getOrCreateUser(event.pubKey) @@ -466,7 +469,7 @@ object LocalCache : ILocalCache { oldUser.latestMetadata = event val newUserMetadata = event.contactMetaData() - if (newUserMetadata != null && justVerify(event)) { + if (newUserMetadata != null && (wasVerified || justVerify(event))) { oldUser.updateUserInfo(newUserMetadata, event) if (relay != null) { oldUser.addRelayBeingUsed(relay, event.createdAt) @@ -482,11 +485,15 @@ object LocalCache : ILocalCache { return false } - fun consume(event: ContactListEvent): Boolean { + fun consume( + event: ContactListEvent, + relay: RelayBriefInfoCache.RelayBriefInfo?, + wasVerified: Boolean, + ): Boolean { val user = getOrCreateUser(event.pubKey) // avoids processing empty contact lists. - if (event.createdAt > (user.latestContactList?.createdAt ?: 0) && !event.tags.isEmpty() && justVerify(event)) { + if (event.createdAt > (user.latestContactList?.createdAt ?: 0) && !event.tags.isEmpty() && (wasVerified || justVerify(event))) { user.updateContactList(event) // Log.d("CL", "Consumed contact list ${user.toNostrUri()} ${event.relays()?.size}") @@ -498,11 +505,15 @@ object LocalCache : ILocalCache { return false } - fun consume(event: BookmarkListEvent): Boolean { + fun consume( + event: BookmarkListEvent, + relay: RelayBriefInfoCache.RelayBriefInfo?, + wasVerified: Boolean, + ): Boolean { val user = getOrCreateUser(event.pubKey) if (user.latestBookmarkList == null || event.createdAt > user.latestBookmarkList!!.createdAt) { if (event.dTag() == "bookmark") { - if (justVerify(event)) { + if (wasVerified || justVerify(event)) { user.updateBookmark(event) return true } @@ -521,31 +532,37 @@ object LocalCache : ILocalCache { fun consume( event: TextNoteEvent, relay: RelayBriefInfoCache.RelayBriefInfo? = null, - ) = consumeRegularEvent(event, relay) + wasVerified: Boolean, + ) = consumeRegularEvent(event, relay, wasVerified) fun consume( event: TorrentEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeRegularEvent(event, relay) + wasVerified: Boolean, + ) = consumeRegularEvent(event, relay, wasVerified) fun consume( event: InteractiveStoryPrologueEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeBaseReplaceable(event, relay) + wasVerified: Boolean, + ) = consumeBaseReplaceable(event, relay, wasVerified) fun consume( event: InteractiveStorySceneEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeBaseReplaceable(event, relay) + wasVerified: Boolean, + ) = consumeBaseReplaceable(event, relay, wasVerified) fun consume( event: InteractiveStoryReadingStateEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeBaseReplaceable(event, relay) + wasVerified: Boolean, + ) = consumeBaseReplaceable(event, relay, wasVerified) fun consumeRegularEvent( event: Event, relay: RelayBriefInfoCache.RelayBriefInfo?, + wasVerified: Boolean, ): Boolean { val note = getOrCreateNote(event.id) val author = getOrCreateUser(event.pubKey) @@ -562,7 +579,7 @@ object LocalCache : ILocalCache { return false } - if (justVerify(event)) { + if (wasVerified || justVerify(event)) { val replyTo = computeReplyTo(event) note.loadEvent(event, author, replyTo) @@ -581,70 +598,80 @@ object LocalCache : ILocalCache { fun consume( event: PictureEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeRegularEvent(event, relay) + wasVerified: Boolean, + ) = consumeRegularEvent(event, relay, wasVerified) fun consume( event: TorrentCommentEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeRegularEvent(event, relay) + wasVerified: Boolean, + ) = consumeRegularEvent(event, relay, wasVerified) fun consume( event: NIP90ContentDiscoveryResponseEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeRegularEvent(event, relay) + wasVerified: Boolean, + ) = consumeRegularEvent(event, relay, wasVerified) fun consume( event: NIP90ContentDiscoveryRequestEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeRegularEvent(event, relay) + wasVerified: Boolean, + ) = consumeRegularEvent(event, relay, wasVerified) fun consume( event: NIP90StatusEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeRegularEvent(event, relay) + wasVerified: Boolean, + ) = consumeRegularEvent(event, relay, wasVerified) fun consume( event: NIP90UserDiscoveryResponseEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeRegularEvent(event, relay) + wasVerified: Boolean, + ) = consumeRegularEvent(event, relay, wasVerified) fun consume( event: NIP90UserDiscoveryRequestEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeRegularEvent(event, relay) + wasVerified: Boolean, + ) = consumeRegularEvent(event, relay, wasVerified) fun consume( event: GitPatchEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeRegularEvent(event, relay) + wasVerified: Boolean, + ) = consumeRegularEvent(event, relay, wasVerified) fun consume( event: GitIssueEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeRegularEvent(event, relay) + wasVerified: Boolean, + ) = consumeRegularEvent(event, relay, wasVerified) fun consume( event: GitReplyEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeRegularEvent(event, relay) + wasVerified: Boolean, + ) = consumeRegularEvent(event, relay, wasVerified) fun consume( event: LongTextNoteEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, + wasVerified: Boolean, ): Boolean { val version = getOrCreateNote(event.id) val note = getOrCreateAddressableNote(event.address()) val author = getOrCreateUser(event.pubKey) - var isVerified = false - - if (version.event == null) { - isVerified = justVerify(event) - if (isVerified) { + val isVerified = + if (version.event == null && (wasVerified || justVerify(event))) { version.loadEvent(event, author, emptyList()) version.moveAllReferencesTo(note) + true + } else { + wasVerified } - } if (relay != null) { author.addRelayBeingUsed(relay, event.createdAt) @@ -652,7 +679,7 @@ object LocalCache : ILocalCache { } // Already processed this event. - if (note.event?.id == event.id) return false + if (note.event?.id == event.id) return wasVerified if (antiSpam.isSpam(event, relay)) { return false @@ -676,20 +703,20 @@ object LocalCache : ILocalCache { fun consume( event: WikiNoteEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, + wasVerified: Boolean, ): Boolean { val version = getOrCreateNote(event.id) val note = getOrCreateAddressableNote(event.address()) val author = getOrCreateUser(event.pubKey) - var isVerified = false - - if (version.event == null) { - isVerified = justVerify(event) - if (isVerified) { + val isVerified = + if (version.event == null && (wasVerified || justVerify(event))) { version.loadEvent(event, author, emptyList()) version.moveAllReferencesTo(note) + true + } else { + wasVerified } - } if (relay != null) { author.addRelayBeingUsed(relay, event.createdAt) @@ -697,7 +724,7 @@ object LocalCache : ILocalCache { } // Already processed this event. - if (note.event?.id == event.id) return false + if (note.event?.id == event.id) return wasVerified if (antiSpam.isSpam(event, relay)) { return false @@ -780,25 +807,26 @@ object LocalCache : ILocalCache { fun consume( event: PollNoteEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeRegularEvent(event, relay) + wasVerified: Boolean, + ) = consumeRegularEvent(event, relay, wasVerified) private fun consume( event: LiveActivitiesEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, + wasVerified: Boolean, ): Boolean { val version = getOrCreateNote(event.id) val note = getOrCreateAddressableNote(event.address()) val author = getOrCreateUser(event.pubKey) - var isVerified = false - - if (version.event == null) { - isVerified = justVerify(event) - if (isVerified) { + val isVerified = + if (version.event == null && (wasVerified || justVerify(event))) { version.loadEvent(event, author, emptyList()) version.moveAllReferencesTo(note) + true + } else { + wasVerified } - } if (note.event?.id == event.id) return false @@ -826,130 +854,152 @@ object LocalCache : ILocalCache { fun consume( event: MuteListEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeBaseReplaceable(event, relay) + wasVerified: Boolean, + ) = consumeBaseReplaceable(event, relay, wasVerified) fun consume( event: CommunityListEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeBaseReplaceable(event, relay) + wasVerified: Boolean, + ) = consumeBaseReplaceable(event, relay, wasVerified) fun consume( event: GitRepositoryEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeBaseReplaceable(event, relay) + wasVerified: Boolean, + ) = consumeBaseReplaceable(event, relay, wasVerified) fun consume( event: ChannelListEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeBaseReplaceable(event, relay) + wasVerified: Boolean, + ) = consumeBaseReplaceable(event, relay, wasVerified) fun consume( event: BlossomServersEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeBaseReplaceable(event, relay) + wasVerified: Boolean, + ) = consumeBaseReplaceable(event, relay, wasVerified) fun consume( event: FileServersEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeBaseReplaceable(event, relay) + wasVerified: Boolean, + ) = consumeBaseReplaceable(event, relay, wasVerified) fun consume( event: PeopleListEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeBaseReplaceable(event, relay) + wasVerified: Boolean, + ) = consumeBaseReplaceable(event, relay, wasVerified) fun consume( event: EphemeralChatListEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeBaseReplaceable(event, relay) + wasVerified: Boolean, + ) = consumeBaseReplaceable(event, relay, wasVerified) fun consume( event: FollowListEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeBaseReplaceable(event, relay) + wasVerified: Boolean, + ) = consumeBaseReplaceable(event, relay, wasVerified) private fun consume( event: AdvertisedRelayListEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeBaseReplaceable(event, relay) + wasVerified: Boolean, + ) = consumeBaseReplaceable(event, relay, wasVerified) private fun consume( event: ChatMessageRelayListEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeBaseReplaceable(event, relay) + wasVerified: Boolean, + ) = consumeBaseReplaceable(event, relay, wasVerified) private fun consume( event: PrivateOutboxRelayListEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeBaseReplaceable(event, relay) + wasVerified: Boolean, + ) = consumeBaseReplaceable(event, relay, wasVerified) private fun consume( event: SearchRelayListEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeBaseReplaceable(event, relay) + wasVerified: Boolean, + ) = consumeBaseReplaceable(event, relay, wasVerified) private fun consume( event: CommunityDefinitionEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeBaseReplaceable(event, relay) + wasVerified: Boolean, + ) = consumeBaseReplaceable(event, relay, wasVerified) fun consume( event: EmojiPackSelectionEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeBaseReplaceable(event, relay) + wasVerified: Boolean, + ) = consumeBaseReplaceable(event, relay, wasVerified) private fun consume( event: EmojiPackEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeBaseReplaceable(event, relay) + wasVerified: Boolean, + ) = consumeBaseReplaceable(event, relay, wasVerified) private fun consume( event: ClassifiedsEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeBaseReplaceable(event, relay) + wasVerified: Boolean, + ) = consumeBaseReplaceable(event, relay, wasVerified) private fun consume( event: PinListEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeBaseReplaceable(event, relay) + wasVerified: Boolean, + ) = consumeBaseReplaceable(event, relay, wasVerified) private fun consume( event: RelaySetEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeBaseReplaceable(event, relay) + wasVerified: Boolean, + ) = consumeBaseReplaceable(event, relay, wasVerified) private fun consume( event: AudioTrackEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeBaseReplaceable(event, relay) + wasVerified: Boolean, + ) = consumeBaseReplaceable(event, relay, wasVerified) private fun consume( event: VideoVerticalEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeBaseReplaceable(event, relay) + wasVerified: Boolean, + ) = consumeBaseReplaceable(event, relay, wasVerified) private fun consume( event: VideoHorizontalEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeBaseReplaceable(event, relay) + wasVerified: Boolean, + ) = consumeBaseReplaceable(event, relay, wasVerified) fun consume( event: StatusEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, + wasVerified: Boolean, ): Boolean { val version = getOrCreateNote(event.id) val note = getOrCreateAddressableNote(event.address()) val author = getOrCreateUser(event.pubKey) - var isVerified = false - - if (version.event == null) { - isVerified = justVerify(event) - if (isVerified) { + val isVerified = + if (version.event == null && (wasVerified || justVerify(event))) { version.loadEvent(event, author, emptyList()) version.moveAllReferencesTo(note) + true + } else { + wasVerified } - } // Already processed this event. if (note.event?.id == event.id) return false @@ -970,11 +1020,13 @@ object LocalCache : ILocalCache { fun consume( event: RelationshipStatusEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeBaseReplaceable(event, relay) + wasVerified: Boolean, + ) = consumeBaseReplaceable(event, relay, wasVerified) fun consume( event: OtsEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, + wasVerified: Boolean, ): Boolean { val version = getOrCreateNote(event.id) val author = getOrCreateUser(event.pubKey) @@ -982,7 +1034,7 @@ object LocalCache : ILocalCache { // Already processed this event. if (version.event?.id == event.id) return false - if (justVerify(event)) { + if (wasVerified || justVerify(event)) { if (version.event == null) { version.loadEvent(event, author, emptyList()) version.flowSet?.ots?.invalidateData() @@ -998,74 +1050,84 @@ object LocalCache : ILocalCache { fun consume( event: BadgeDefinitionEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeBaseReplaceable(event, relay) + wasVerified: Boolean, + ) = consumeBaseReplaceable(event, relay, wasVerified) fun consume( event: BadgeProfilesEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeBaseReplaceable(event, relay) + wasVerified: Boolean, + ) = consumeBaseReplaceable(event, relay, wasVerified) fun consume( event: BadgeAwardEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeRegularEvent(event, relay) + wasVerified: Boolean, + ) = consumeRegularEvent(event, relay, wasVerified) private fun consume( event: NNSEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeBaseReplaceable(event, relay) + wasVerified: Boolean, + ) = consumeBaseReplaceable(event, relay, wasVerified) fun consume( event: AppDefinitionEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeBaseReplaceable(event, relay) + wasVerified: Boolean, + ) = consumeBaseReplaceable(event, relay, wasVerified) private fun consume( event: CalendarEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeBaseReplaceable(event, relay) + wasVerified: Boolean, + ) = consumeBaseReplaceable(event, relay, wasVerified) private fun consume( event: CalendarDateSlotEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeBaseReplaceable(event, relay) + wasVerified: Boolean, + ) = consumeBaseReplaceable(event, relay, wasVerified) private fun consume( event: CalendarTimeSlotEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeBaseReplaceable(event, relay) + wasVerified: Boolean, + ) = consumeBaseReplaceable(event, relay, wasVerified) private fun consume( event: CalendarRSVPEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeBaseReplaceable(event, relay) + wasVerified: Boolean, + ) = consumeBaseReplaceable(event, relay, wasVerified) private fun consumeBaseReplaceable( event: BaseAddressableEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, + wasVerified: Boolean, ): Boolean { val version = getOrCreateNote(event.id) val replaceableNote = getOrCreateAddressableNote(event.address()) val author = getOrCreateUser(event.pubKey) - var verified = false + + val isVerified = + if (version.event == null && (wasVerified || justVerify(event))) { + version.loadEvent(event, author, emptyList()) + version.moveAllReferencesTo(replaceableNote) + true + } else { + wasVerified + } if (relay != null) { author.addRelayBeingUsed(relay, event.createdAt) replaceableNote.addRelay(relay) } - if (version.event == null) { - verified = justVerify(event) - if (verified) { - version.loadEvent(event, author, emptyList()) - version.moveAllReferencesTo(replaceableNote) - } - } - // Already processed this event. - if (replaceableNote.event?.id == event.id) return verified + if (replaceableNote.event?.id == event.id) return isVerified - if (event.createdAt > (replaceableNote.createdAt() ?: 0) && (verified || justVerify(event))) { + if (event.createdAt > (replaceableNote.createdAt() ?: 0) && (isVerified || justVerify(event))) { replaceableNote.loadEvent(event, author, computeReplyTo(event)) refreshObservers(replaceableNote) @@ -1079,16 +1141,19 @@ object LocalCache : ILocalCache { fun consume( event: AppRecommendationEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeBaseReplaceable(event, relay) + wasVerified: Boolean, + ) = consumeBaseReplaceable(event, relay, wasVerified) fun consume( event: AppSpecificDataEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeBaseReplaceable(event, relay) + wasVerified: Boolean, + ) = consumeBaseReplaceable(event, relay, wasVerified) fun consume( event: PrivateDmEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, + wasVerified: Boolean, ): Boolean { val note = getOrCreateNote(event.id) val author = getOrCreateUser(event.pubKey) @@ -1101,7 +1166,7 @@ object LocalCache : ILocalCache { // Already processed this event. if (note.event != null) return false - if (justVerify(event)) { + if (wasVerified || justVerify(event)) { val recipient = event.verifiedRecipientPubKey()?.let { getOrCreateUser(it) } // Log.d("PM", "${author.toBestDisplayName()} to ${recipient?.toBestDisplayName()}") @@ -1123,8 +1188,12 @@ object LocalCache : ILocalCache { return false } - fun consume(event: DeletionEvent): Boolean { - if (deletionIndex.add(event, false)) { + fun consume( + event: DeletionEvent, + relay: RelayBriefInfoCache.RelayBriefInfo?, + wasVerified: Boolean, + ): Boolean { + if (deletionIndex.add(event, wasVerified)) { var deletedAtLeastOne = false event @@ -1272,13 +1341,14 @@ object LocalCache : ILocalCache { fun consume( event: RepostEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, + wasVerified: Boolean, ): Boolean { val note = getOrCreateNote(event.id) // Already processed this event. if (note.event != null) return false - if (justVerify(event)) { + if (wasVerified || justVerify(event)) { val author = getOrCreateUser(event.pubKey) val repliesTo = computeReplyTo(event) @@ -1288,7 +1358,7 @@ object LocalCache : ILocalCache { repliesTo.forEach { it.addBoost(note) } event.containedPost()?.let { - justConsumeInner(it, relay) + justConsumeInner(it, relay, false) } refreshObservers(note) @@ -1301,13 +1371,14 @@ object LocalCache : ILocalCache { fun consume( event: GenericRepostEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, + wasVerified: Boolean, ): Boolean { val note = getOrCreateNote(event.id) // Already processed this event. if (note.event != null) return false - if (justVerify(event)) { + if (wasVerified || justVerify(event)) { val author = getOrCreateUser(event.pubKey) val repliesTo = computeReplyTo(event) @@ -1317,7 +1388,7 @@ object LocalCache : ILocalCache { repliesTo.forEach { it.addBoost(note) } event.containedPost()?.let { - justConsumeInner(it, relay) + justConsumeInner(it, relay, false) } refreshObservers(note) @@ -1331,13 +1402,14 @@ object LocalCache : ILocalCache { fun consume( event: CommunityPostApprovalEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, + wasVerified: Boolean, ): Boolean { val note = getOrCreateNote(event.id) // Already processed this event. if (note.event != null) return false - if (justVerify(event)) { + if (wasVerified || justVerify(event)) { val author = getOrCreateUser(event.pubKey) val communities = event.communityAddresses() @@ -1351,7 +1423,7 @@ object LocalCache : ILocalCache { repliesTo.forEach { it.addBoost(note) } event.containedPost()?.let { - justConsumeInner(it, relay) + justConsumeInner(it, relay, false) } refreshObservers(note) @@ -1362,13 +1434,17 @@ object LocalCache : ILocalCache { return false } - fun consume(event: ReactionEvent): Boolean { + fun consume( + event: ReactionEvent, + relay: RelayBriefInfoCache.RelayBriefInfo?, + wasVerified: Boolean, + ): Boolean { val note = getOrCreateNote(event.id) // Already processed this event. if (note.event != null) return true - if (justVerify(event)) { + if (wasVerified || justVerify(event)) { val author = getOrCreateUser(event.pubKey) val repliesTo = computeReplyTo(event) @@ -1387,6 +1463,7 @@ object LocalCache : ILocalCache { fun consume( event: ReportEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, + wasVerified: Boolean, ): Boolean { val note = getOrCreateNote(event.id) val author = getOrCreateUser(event.pubKey) @@ -1399,7 +1476,7 @@ object LocalCache : ILocalCache { // Already processed this event. if (note.event != null) return false - if (justVerify(event)) { + if (wasVerified || justVerify(event)) { val mentions = event.reportedAuthor().mapNotNull { checkGetOrCreateUser(it.pubkey) } val repliesTo = computeReplyTo(event) @@ -1430,27 +1507,28 @@ object LocalCache : ILocalCache { fun consume( event: ChannelCreateEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, + wasVerified: Boolean, ): Boolean { // Log.d("MT", "New Event ${event.content} ${event.id.toHex()}") val oldChannel = getOrCreateChannel(event.id) { PublicChatChannel(it) } val author = getOrCreateUser(event.pubKey) - - var isVerified = false - val note = getOrCreateNote(event.id) - if (note.event == null) { - isVerified = justVerify(event) - if (isVerified) { + + val isVerified = + if (note.event == null && (wasVerified || justVerify(event))) { oldChannel.addNote(note, relay) note.loadEvent(event, author, emptyList()) refreshObservers(note) + true + } else { + wasVerified } - } if (event.createdAt <= oldChannel.updatedMetadataAt) { return false // older data, does nothing } + if (oldChannel.creator == null || oldChannel.creator == author) { if (oldChannel is PublicChatChannel && (isVerified || justVerify(event))) { oldChannel.updateChannelInfo(author, event) @@ -1463,28 +1541,26 @@ object LocalCache : ILocalCache { fun consume( event: ChannelMetadataEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, + wasVerified: Boolean, ): Boolean { val channelId = event.channelId() - // Log.d("MT", "New PublicChatMetadata ${event.channelInfo()}") if (channelId.isNullOrBlank()) return false - var isVerified = false - // new event val oldChannel = checkGetOrCreateChannel(channelId) ?: return false val author = getOrCreateUser(event.pubKey) - if (event.createdAt > oldChannel.updatedMetadataAt) { - if (oldChannel is PublicChatChannel) { - isVerified = justVerify(event) - if (isVerified) { + val isVerified = + if (event.createdAt > oldChannel.updatedMetadataAt) { + if (oldChannel is PublicChatChannel && (wasVerified || justVerify(event))) { oldChannel.updateChannelInfo(author, event) + true + } else { + wasVerified } + } else { + wasVerified } - } else { - // Log.d("MT","Relay sent a previous Metadata Event ${oldUser.toBestDisplayName()} - // ${formattedDateTime(event.createdAt)} > ${formattedDateTime(oldUser.updatedAt)}") - } val note = getOrCreateNote(event.id) if (note.event == null && (isVerified || justVerify(event))) { @@ -1500,6 +1576,7 @@ object LocalCache : ILocalCache { fun consume( event: ChannelMessageEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, + wasVerified: Boolean, ): Boolean { val channelId = event.channelId() @@ -1524,7 +1601,7 @@ object LocalCache : ILocalCache { return false } - if (justVerify(event)) { + if (wasVerified || justVerify(event)) { val replyTo = computeReplyTo(event) note.loadEvent(event, author, replyTo) @@ -1544,6 +1621,7 @@ object LocalCache : ILocalCache { fun consume( event: EphemeralChatEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, + wasVerified: Boolean, ): Boolean { val relayUrl = event.relay().ifBlank { return false } @@ -1568,7 +1646,7 @@ object LocalCache : ILocalCache { return false } - if (justVerify(event)) { + if (wasVerified || justVerify(event)) { note.loadEvent(event, author, emptyList()) refreshObservers(note) @@ -1582,11 +1660,13 @@ object LocalCache : ILocalCache { fun consume( event: CommentEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeRegularEvent(event, relay) + wasVerified: Boolean, + ) = consumeRegularEvent(event, relay, wasVerified) fun consume( event: LiveActivitiesChatMessageEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, + wasVerified: Boolean, ): Boolean { val activityAddress = event.activityAddress() ?: return false @@ -1609,7 +1689,7 @@ object LocalCache : ILocalCache { return false } - if (justVerify(event)) { + if (wasVerified || justVerify(event)) { val replyTo = computeReplyTo(event) note.loadEvent(event, author, replyTo) @@ -1626,26 +1706,35 @@ object LocalCache : ILocalCache { } @Suppress("UNUSED_PARAMETER") - fun consume(event: ChannelHideMessageEvent): Boolean = false + fun consume( + event: ChannelHideMessageEvent, + relay: RelayBriefInfoCache.RelayBriefInfo?, + wasVerified: Boolean, + ): Boolean = false @Suppress("UNUSED_PARAMETER") - fun consume(event: ChannelMuteUserEvent): Boolean = false + fun consume( + event: ChannelMuteUserEvent, + relay: RelayBriefInfoCache.RelayBriefInfo?, + wasVerified: Boolean, + ): Boolean = false fun consume( event: LnZapEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, + wasVerified: Boolean, ): Boolean { val note = getOrCreateNote(event.id) // Already processed this event. if (note.event != null) return false - if (justVerify(event)) { + if (wasVerified || justVerify(event)) { val existingZapRequest = event.zapRequest?.id?.let { getNoteIfExists(it) } if (existingZapRequest == null || existingZapRequest.event == null) { // tries to add it event.zapRequest?.let { - justConsumeInner(it, relay) + justConsumeInner(it, relay, false) } } @@ -1673,13 +1762,17 @@ object LocalCache : ILocalCache { return false } - fun consume(event: LnZapRequestEvent): Boolean { + fun consume( + event: LnZapRequestEvent, + relay: RelayBriefInfoCache.RelayBriefInfo?, + wasVerified: Boolean, + ): Boolean { val note = getOrCreateNote(event.id) // Already processed this event. if (note.event != null) return false - if (justVerify(event)) { + if (wasVerified || justVerify(event)) { val author = getOrCreateUser(event.pubKey) val mentions = event.zappedAuthor().mapNotNull { checkGetOrCreateUser(it) } val repliesTo = computeReplyTo(event) @@ -1700,31 +1793,37 @@ object LocalCache : ILocalCache { fun consume( event: AudioHeaderEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeRegularEvent(event, relay) + wasVerified: Boolean, + ) = consumeRegularEvent(event, relay, wasVerified) fun consume( event: FileHeaderEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeRegularEvent(event, relay) + wasVerified: Boolean, + ) = consumeRegularEvent(event, relay, wasVerified) fun consume( event: ProfileGalleryEntryEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeRegularEvent(event, relay) + wasVerified: Boolean, + ) = consumeRegularEvent(event, relay, wasVerified) fun consume( event: FileStorageHeaderEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeRegularEvent(event, relay) + wasVerified: Boolean, + ) = consumeRegularEvent(event, relay, wasVerified) fun consume( event: FhirResourceEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeRegularEvent(event, relay) + wasVerified: Boolean, + ) = consumeRegularEvent(event, relay, wasVerified) fun consume( event: TextNoteModificationEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, + wasVerified: Boolean, ): Boolean { val note = getOrCreateNote(event.id) val author = getOrCreateUser(event.pubKey) @@ -1737,7 +1836,7 @@ object LocalCache : ILocalCache { // Already processed this event. if (note.event != null) return false - if (justVerify(event)) { + if (wasVerified || justVerify(event)) { note.loadEvent(event, author, emptyList()) event.editedNote()?.let { @@ -1759,11 +1858,13 @@ object LocalCache : ILocalCache { fun consume( event: HighlightEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, - ) = consumeRegularEvent(event, relay) + wasVerified: Boolean, + ) = consumeRegularEvent(event, relay, wasVerified) fun consume( event: FileStorageEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, + wasVerified: Boolean, ): Boolean { val note = getOrCreateNote(event.id) val author = getOrCreateUser(event.pubKey) @@ -1773,15 +1874,12 @@ object LocalCache : ILocalCache { note.addRelay(relay) } - var isVerified = false - - try { - val cachePath = Amethyst.instance.nip95cache - cachePath.mkdirs() - val file = File(cachePath, event.id) - if (!file.exists()) { - isVerified = justVerify(event) - if (isVerified) { + var isVerified = + try { + val cachePath = Amethyst.instance.nip95cache + cachePath.mkdirs() + val file = File(cachePath, event.id) + if (!file.exists() && (wasVerified || justVerify(event))) { val stream = FileOutputStream(file) stream.write(event.decode()) stream.close() @@ -1789,11 +1887,14 @@ object LocalCache : ILocalCache { "FileStorageEvent", "NIP95 File received from ${relay?.url} and saved to disk as $file", ) + true + } else { + wasVerified } + } catch (e: IOException) { + Log.e("FileStorageEvent", "FileStorageEvent save to disk error: " + event.id, e) + wasVerified } - } catch (e: IOException) { - Log.e("FileStorageEvent", "FileStorageEvent save to disk error: " + event.id, e) - } // Already processed this event. if (note.event != null) return false @@ -1816,6 +1917,7 @@ object LocalCache : ILocalCache { private fun consume( event: ChatMessageEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, + wasVerified: Boolean, ): Boolean { val note = getOrCreateNote(event.id) val author = getOrCreateUser(event.pubKey) @@ -1828,39 +1930,44 @@ object LocalCache : ILocalCache { // Already processed this event. if (note.event != null) return false - val recipientsHex = event.groupMembers() - val recipients = recipientsHex.mapNotNull { checkGetOrCreateUser(it) }.toSet() + if (wasVerified || justVerify(event)) { + val recipientsHex = event.groupMembers() + val recipients = recipientsHex.mapNotNull { checkGetOrCreateUser(it) }.toSet() - // Log.d("PM", "${author.toBestDisplayName()} to ${recipient?.toBestDisplayName()}") + // Log.d("PM", "${author.toBestDisplayName()} to ${recipient?.toBestDisplayName()}") - val repliesTo = computeReplyTo(event) + val repliesTo = computeReplyTo(event) - note.loadEvent(event, author, repliesTo) + note.loadEvent(event, author, repliesTo) - if (recipients.isNotEmpty()) { - recipients.forEach { - val groupMinusRecipient = recipientsHex.minus(it.pubkeyHex) + if (recipients.isNotEmpty()) { + recipients.forEach { + val groupMinusRecipient = recipientsHex.minus(it.pubkeyHex) - val authorGroup = - if (groupMinusRecipient.isEmpty()) { - // note to self - ChatroomKey(persistentSetOf(it.pubkeyHex)) - } else { - ChatroomKey(groupMinusRecipient.toImmutableSet()) - } + val authorGroup = + if (groupMinusRecipient.isEmpty()) { + // note to self + ChatroomKey(persistentSetOf(it.pubkeyHex)) + } else { + ChatroomKey(groupMinusRecipient.toImmutableSet()) + } - it.addMessage(authorGroup, note) + it.addMessage(authorGroup, note) + } } + + refreshObservers(note) + + return true } - refreshObservers(note) - - return true + return false } private fun consume( event: ChatMessageEncryptedFileHeaderEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, + wasVerified: Boolean, ): Boolean { val note = getOrCreateNote(event.id) val author = getOrCreateUser(event.pubKey) @@ -1873,39 +1980,44 @@ object LocalCache : ILocalCache { // Already processed this event. if (note.event != null) return false - val recipientsHex = event.groupMembers() - val recipients = recipientsHex.mapNotNull { checkGetOrCreateUser(it) }.toSet() + if (wasVerified || justVerify(event)) { + val recipientsHex = event.groupMembers() + val recipients = recipientsHex.mapNotNull { checkGetOrCreateUser(it) }.toSet() - // Log.d("PM", "${author.toBestDisplayName()} to ${recipient?.toBestDisplayName()}") + // Log.d("PM", "${author.toBestDisplayName()} to ${recipient?.toBestDisplayName()}") - val repliesTo = computeReplyTo(event) + val repliesTo = computeReplyTo(event) - note.loadEvent(event, author, repliesTo) + note.loadEvent(event, author, repliesTo) - if (recipients.isNotEmpty()) { - recipients.forEach { - val groupMinusRecipient = recipientsHex.minus(it.pubkeyHex) + if (recipients.isNotEmpty()) { + recipients.forEach { + val groupMinusRecipient = recipientsHex.minus(it.pubkeyHex) - val authorGroup = - if (groupMinusRecipient.isEmpty()) { - // note to self - ChatroomKey(persistentSetOf(it.pubkeyHex)) - } else { - ChatroomKey(groupMinusRecipient.toImmutableSet()) - } + val authorGroup = + if (groupMinusRecipient.isEmpty()) { + // note to self + ChatroomKey(persistentSetOf(it.pubkeyHex)) + } else { + ChatroomKey(groupMinusRecipient.toImmutableSet()) + } - it.addMessage(authorGroup, note) + it.addMessage(authorGroup, note) + } } + + refreshObservers(note) + + return true } - refreshObservers(note) - - return true + return false } fun consume( event: SealedRumorEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, + wasVerified: Boolean, ): Boolean { val note = getOrCreateNote(event.id) val author = getOrCreateUser(event.pubKey) @@ -1916,11 +2028,9 @@ object LocalCache : ILocalCache { } // Already processed this event. - if (note.event != null) { - val note = (note.event as? SealedRumorEvent)?.innerEventId?.let { getNoteIfExists(it) } - note?.event?.let { justConsumeInner(it, relay) } - return false - } else if (justVerify(event)) { + if (note.event != null) return false + + if (wasVerified || justVerify(event)) { note.loadEvent(event, author, emptyList()) refreshObservers(note) return true @@ -1932,6 +2042,7 @@ object LocalCache : ILocalCache { fun consume( event: GiftWrapEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, + wasVerified: Boolean, ): Boolean { val note = getOrCreateNote(event.id) val author = getOrCreateUser(event.pubKey) @@ -1941,11 +2052,9 @@ object LocalCache : ILocalCache { } // Already processed this event. - if (note.event != null) { - val note = (note.event as? GiftWrapEvent)?.innerEventId?.let { getNoteIfExists(it) } - note?.event?.let { justConsumeInner(it, relay) } - return false - } else if (justVerify(event)) { + if (note.event != null) return false + + if (wasVerified || justVerify(event)) { note.loadEvent(event, author, emptyList()) refreshObservers(note) return true @@ -1954,7 +2063,11 @@ object LocalCache : ILocalCache { return false } - fun consume(event: LnZapPaymentRequestEvent): Boolean { + fun consume( + event: LnZapPaymentRequestEvent, + relay: RelayBriefInfoCache.RelayBriefInfo?, + wasVerified: Boolean, + ): Boolean { // Does nothing without a response callback. return true } @@ -1962,24 +2075,35 @@ object LocalCache : ILocalCache { fun consume( event: LnZapPaymentRequestEvent, zappedNote: Note?, + wasVerified: Boolean, onResponse: (LnZapPaymentResponseEvent) -> Unit, - ) { + ): Boolean { val note = getOrCreateNote(event.id) val author = getOrCreateUser(event.pubKey) // Already processed this event. - if (note.event != null) return + if (note.event != null) return false - note.loadEvent(event, author, emptyList()) + if (wasVerified || justVerify(event)) { + note.loadEvent(event, author, emptyList()) - zappedNote?.addZapPayment(note, null) + zappedNote?.addZapPayment(note, null) - awaitingPaymentRequests.put(event.id, Pair(zappedNote, onResponse)) + awaitingPaymentRequests.put(event.id, Pair(zappedNote, onResponse)) - refreshObservers(note) + refreshObservers(note) + + return true + } + + return false } - fun consume(event: LnZapPaymentResponseEvent): Boolean { + fun consume( + event: LnZapPaymentResponseEvent, + relay: RelayBriefInfoCache.RelayBriefInfo?, + wasVerified: Boolean, + ): Boolean { val requestId = event.requestId() val pair = awaitingPaymentRequests[requestId] ?: return false @@ -1993,7 +2117,7 @@ object LocalCache : ILocalCache { // Already processed this event. if (note.event != null) return false - if (justVerify(event)) { + if (wasVerified || justVerify(event)) { note.loadEvent(event, author, emptyList()) requestNote?.let { request -> zappedNote?.addZapPayment(request, note) } @@ -2521,7 +2645,7 @@ object LocalCache : ILocalCache { event.checkSignature() } catch (e: Exception) { if (e is CancellationException) throw e - Log.w("Event failed retest ${event.kind}", (e.message ?: "") + event.toJson()) + Log.w("Event Verification Failed", "Kind: ${event.kind} from ${dateFormatter(event.createdAt, "", "")} with message ${e.message}: ${event.toJson()}") } false } else { @@ -2532,14 +2656,10 @@ object LocalCache : ILocalCache { fun consume( event: DraftEvent, relay: RelayBriefInfoCache.RelayBriefInfo?, + wasVerified: Boolean, ): Boolean { if (!event.isDeleted()) { - if (consumeBaseReplaceable(event, relay)) { - event.allCache().forEach { - it?.let { - indexDraftAsRealEvent(event, it) - } - } + if (consumeBaseReplaceable(event, relay, wasVerified)) { return true } } @@ -2691,9 +2811,12 @@ object LocalCache : ILocalCache { } } + fun justConsumeMyOwnEvent(event: Event) = justConsumeInner(event, null, true) + fun justConsume( event: Event, relay: Relay?, + wasVerified: Boolean, ): Boolean { if (deletionIndex.hasBeenDeleted(event)) { // update relay with deletion event from another. @@ -2718,105 +2841,106 @@ object LocalCache : ILocalCache { } } - return justConsumeInner(event, relay?.brief) + return justConsumeInner(event, relay?.brief, wasVerified) } fun justConsumeInner( event: Event, relay: RelayBriefInfoCache.RelayBriefInfo?, + wasVerified: Boolean, ): Boolean = try { when (event) { - is AdvertisedRelayListEvent -> consume(event, relay) - is AppDefinitionEvent -> consume(event, relay) - is AppRecommendationEvent -> consume(event, relay) - is AppSpecificDataEvent -> consume(event, relay) - is AudioHeaderEvent -> consume(event, relay) - is AudioTrackEvent -> consume(event, relay) - is BadgeAwardEvent -> consume(event, relay) - is BadgeDefinitionEvent -> consume(event, relay) - is BadgeProfilesEvent -> consume(event, relay) - is BlossomServersEvent -> consume(event, relay) - is BookmarkListEvent -> consume(event) - is CalendarEvent -> consume(event, relay) - is CalendarDateSlotEvent -> consume(event, relay) - is CalendarTimeSlotEvent -> consume(event, relay) - is CalendarRSVPEvent -> consume(event, relay) - is ChannelCreateEvent -> consume(event, relay) - is ChannelListEvent -> consume(event, relay) - is ChannelHideMessageEvent -> consume(event) - is ChannelMessageEvent -> consume(event, relay) - is ChannelMetadataEvent -> consume(event, relay) - is ChannelMuteUserEvent -> consume(event) - is ChatMessageEncryptedFileHeaderEvent -> consume(event, relay) - is ChatMessageEvent -> consume(event, relay) - is ChatMessageRelayListEvent -> consume(event, relay) - is ClassifiedsEvent -> consume(event, relay) - is CommentEvent -> consume(event, relay) - is CommunityDefinitionEvent -> consume(event, relay) - is CommunityListEvent -> consume(event, relay) - is CommunityPostApprovalEvent -> consume(event, relay) - is ContactListEvent -> consume(event) - is DeletionEvent -> consume(event) - is DraftEvent -> consume(event, relay) - is EmojiPackEvent -> consume(event, relay) - is EmojiPackSelectionEvent -> consume(event, relay) - is EphemeralChatEvent -> consume(event, relay) - is EphemeralChatListEvent -> consume(event, relay) - is GenericRepostEvent -> consume(event, relay) - is FhirResourceEvent -> consume(event, relay) - is FileHeaderEvent -> consume(event, relay) - is ProfileGalleryEntryEvent -> consume(event, relay) - is FileServersEvent -> consume(event, relay) - is FileStorageEvent -> consume(event, relay) - is FileStorageHeaderEvent -> consume(event, relay) - is FollowListEvent -> consume(event, relay) - is GiftWrapEvent -> consume(event, relay) - is GitIssueEvent -> consume(event, relay) - is GitReplyEvent -> consume(event, relay) - is GitPatchEvent -> consume(event, relay) - is GitRepositoryEvent -> consume(event, relay) - is HighlightEvent -> consume(event, relay) - is InteractiveStoryPrologueEvent -> consume(event, relay) - is InteractiveStorySceneEvent -> consume(event, relay) - is InteractiveStoryReadingStateEvent -> consume(event, relay) - is LiveActivitiesEvent -> consume(event, relay) - is LiveActivitiesChatMessageEvent -> consume(event, relay) - is LnZapEvent -> consume(event, relay) - is LnZapRequestEvent -> consume(event) - is NIP90StatusEvent -> consume(event, relay) - is NIP90ContentDiscoveryResponseEvent -> consume(event, relay) - is NIP90ContentDiscoveryRequestEvent -> consume(event, relay) - is NIP90UserDiscoveryResponseEvent -> consume(event, relay) - is NIP90UserDiscoveryRequestEvent -> consume(event, relay) - is LnZapPaymentRequestEvent -> consume(event) - is LnZapPaymentResponseEvent -> consume(event) - is LongTextNoteEvent -> consume(event, relay) - is MetadataEvent -> consume(event, relay) - is MuteListEvent -> consume(event, relay) - is NNSEvent -> consume(event, relay) - is OtsEvent -> consume(event, relay) - is PictureEvent -> consume(event, relay) - is PrivateDmEvent -> consume(event, relay) - is PrivateOutboxRelayListEvent -> consume(event, relay) - is PinListEvent -> consume(event, relay) - is PeopleListEvent -> consume(event, relay) - is PollNoteEvent -> consume(event, relay) - is ReactionEvent -> consume(event) - is RelationshipStatusEvent -> consume(event, relay) - is RelaySetEvent -> consume(event, relay) - is ReportEvent -> consume(event, relay) - is RepostEvent -> consume(event, relay) - is SealedRumorEvent -> consume(event, relay) - is SearchRelayListEvent -> consume(event, relay) - is StatusEvent -> consume(event, relay) - is TextNoteEvent -> consume(event, relay) - is TextNoteModificationEvent -> consume(event, relay) - is TorrentEvent -> consume(event, relay) - is TorrentCommentEvent -> consume(event, relay) - is VideoHorizontalEvent -> consume(event, relay) - is VideoVerticalEvent -> consume(event, relay) - is WikiNoteEvent -> consume(event, relay) + is AdvertisedRelayListEvent -> consume(event, relay, wasVerified) + is AppDefinitionEvent -> consume(event, relay, wasVerified) + is AppRecommendationEvent -> consume(event, relay, wasVerified) + is AppSpecificDataEvent -> consume(event, relay, wasVerified) + is AudioHeaderEvent -> consume(event, relay, wasVerified) + is AudioTrackEvent -> consume(event, relay, wasVerified) + is BadgeAwardEvent -> consume(event, relay, wasVerified) + is BadgeDefinitionEvent -> consume(event, relay, wasVerified) + is BadgeProfilesEvent -> consume(event, relay, wasVerified) + is BlossomServersEvent -> consume(event, relay, wasVerified) + is BookmarkListEvent -> consume(event, relay, wasVerified) + is CalendarEvent -> consume(event, relay, wasVerified) + is CalendarDateSlotEvent -> consume(event, relay, wasVerified) + is CalendarTimeSlotEvent -> consume(event, relay, wasVerified) + is CalendarRSVPEvent -> consume(event, relay, wasVerified) + is ChannelCreateEvent -> consume(event, relay, wasVerified) + is ChannelListEvent -> consume(event, relay, wasVerified) + is ChannelHideMessageEvent -> consume(event, relay, wasVerified) + is ChannelMessageEvent -> consume(event, relay, wasVerified) + is ChannelMetadataEvent -> consume(event, relay, wasVerified) + is ChannelMuteUserEvent -> consume(event, relay, wasVerified) + is ChatMessageEncryptedFileHeaderEvent -> consume(event, relay, wasVerified) + is ChatMessageEvent -> consume(event, relay, wasVerified) + is ChatMessageRelayListEvent -> consume(event, relay, wasVerified) + is ClassifiedsEvent -> consume(event, relay, wasVerified) + is CommentEvent -> consume(event, relay, wasVerified) + is CommunityDefinitionEvent -> consume(event, relay, wasVerified) + is CommunityListEvent -> consume(event, relay, wasVerified) + is CommunityPostApprovalEvent -> consume(event, relay, wasVerified) + is ContactListEvent -> consume(event, relay, wasVerified) + is DeletionEvent -> consume(event, relay, wasVerified) + is DraftEvent -> consume(event, relay, wasVerified) + is EmojiPackEvent -> consume(event, relay, wasVerified) + is EmojiPackSelectionEvent -> consume(event, relay, wasVerified) + is EphemeralChatEvent -> consume(event, relay, wasVerified) + is EphemeralChatListEvent -> consume(event, relay, wasVerified) + is GenericRepostEvent -> consume(event, relay, wasVerified) + is FhirResourceEvent -> consume(event, relay, wasVerified) + is FileHeaderEvent -> consume(event, relay, wasVerified) + is ProfileGalleryEntryEvent -> consume(event, relay, wasVerified) + is FileServersEvent -> consume(event, relay, wasVerified) + is FileStorageEvent -> consume(event, relay, wasVerified) + is FileStorageHeaderEvent -> consume(event, relay, wasVerified) + is FollowListEvent -> consume(event, relay, wasVerified) + is GiftWrapEvent -> consume(event, relay, wasVerified) + is GitIssueEvent -> consume(event, relay, wasVerified) + is GitReplyEvent -> consume(event, relay, wasVerified) + is GitPatchEvent -> consume(event, relay, wasVerified) + is GitRepositoryEvent -> consume(event, relay, wasVerified) + is HighlightEvent -> consume(event, relay, wasVerified) + is InteractiveStoryPrologueEvent -> consume(event, relay, wasVerified) + is InteractiveStorySceneEvent -> consume(event, relay, wasVerified) + is InteractiveStoryReadingStateEvent -> consume(event, relay, wasVerified) + is LiveActivitiesEvent -> consume(event, relay, wasVerified) + is LiveActivitiesChatMessageEvent -> consume(event, relay, wasVerified) + is LnZapEvent -> consume(event, relay, wasVerified) + is LnZapRequestEvent -> consume(event, relay, wasVerified) + is NIP90StatusEvent -> consume(event, relay, wasVerified) + is NIP90ContentDiscoveryResponseEvent -> consume(event, relay, wasVerified) + is NIP90ContentDiscoveryRequestEvent -> consume(event, relay, wasVerified) + is NIP90UserDiscoveryResponseEvent -> consume(event, relay, wasVerified) + is NIP90UserDiscoveryRequestEvent -> consume(event, relay, wasVerified) + is LnZapPaymentRequestEvent -> consume(event, relay, wasVerified) + is LnZapPaymentResponseEvent -> consume(event, relay, wasVerified) + is LongTextNoteEvent -> consume(event, relay, wasVerified) + is MetadataEvent -> consume(event, relay, wasVerified) + is MuteListEvent -> consume(event, relay, wasVerified) + is NNSEvent -> consume(event, relay, wasVerified) + is OtsEvent -> consume(event, relay, wasVerified) + is PictureEvent -> consume(event, relay, wasVerified) + is PrivateDmEvent -> consume(event, relay, wasVerified) + is PrivateOutboxRelayListEvent -> consume(event, relay, wasVerified) + is PinListEvent -> consume(event, relay, wasVerified) + is PeopleListEvent -> consume(event, relay, wasVerified) + is PollNoteEvent -> consume(event, relay, wasVerified) + is ReactionEvent -> consume(event, relay, wasVerified) + is RelationshipStatusEvent -> consume(event, relay, wasVerified) + is RelaySetEvent -> consume(event, relay, wasVerified) + is ReportEvent -> consume(event, relay, wasVerified) + is RepostEvent -> consume(event, relay, wasVerified) + is SealedRumorEvent -> consume(event, relay, wasVerified) + is SearchRelayListEvent -> consume(event, relay, wasVerified) + is StatusEvent -> consume(event, relay, wasVerified) + is TextNoteEvent -> consume(event, relay, wasVerified) + is TextNoteModificationEvent -> consume(event, relay, wasVerified) + is TorrentEvent -> consume(event, relay, wasVerified) + is TorrentCommentEvent -> consume(event, relay, wasVerified) + is VideoHorizontalEvent -> consume(event, relay, wasVerified) + is VideoVerticalEvent -> consume(event, relay, wasVerified) + is WikiNoteEvent -> consume(event, relay, wasVerified) else -> { Log.w("Event Not Supported", event.toJson()) false diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/notifications/EventNotificationConsumer.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/notifications/EventNotificationConsumer.kt index 5192603b9..d5572ffe4 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/notifications/EventNotificationConsumer.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/notifications/EventNotificationConsumer.kt @@ -174,7 +174,7 @@ class EventNotificationConsumer( when (event) { is GiftWrapEvent -> { - if (LocalCache.justConsume(event, null)) { + if (LocalCache.justConsume(event, null, false)) { // new event event.unwrap(signer) { // clear the encrypted payload to save memory @@ -185,22 +185,21 @@ class EventNotificationConsumer( } } is SealedRumorEvent -> { - if (LocalCache.justConsume(event, null)) { + if (LocalCache.justConsume(event, null, false)) { // new event event.unseal(signer) { // clear the encrypted payload to save memory LocalCache.getOrCreateNote(event.id).event = event.copyNoContent() // this is not verifiable - if (!LocalCache.hasConsumed(it)) { - LocalCache.justConsume(it, null) + if (LocalCache.justConsume(it, null, true)) { onReady(it) } } } } else -> { - LocalCache.justConsume(event, null) + LocalCache.justConsume(event, null, false) onReady(event) } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/CacheClientConnector.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/CacheClientConnector.kt index ceabe8cfc..168419aad 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/CacheClientConnector.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/CacheClientConnector.kt @@ -33,7 +33,7 @@ class CacheClientConnector( ) { val receiver = EventCollector(client) { event, relay -> - cache.justConsume(event, relay) + cache.justConsume(event, relay, false) } val confirmationWatcher = diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/searchCommand/subassemblies/SearchWatcherSubAssembler.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/searchCommand/subassemblies/SearchWatcherSubAssembler.kt index 42c029996..2823f76c7 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/searchCommand/subassemblies/SearchWatcherSubAssembler.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/searchCommand/subassemblies/SearchWatcherSubAssembler.kt @@ -70,7 +70,7 @@ class SearchWatcherSubAssembler( is Note -> filterByEvent(parsed.hex) is NEvent -> filterByEvent(parsed.hex) is NEmbed -> { - cache.justConsume(parsed.event, null) + cache.justConsume(parsed.event, null, false) emptyList() } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/MainActivity.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/MainActivity.kt index 343a12416..916edcf22 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/MainActivity.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/MainActivity.kt @@ -183,7 +183,7 @@ fun uriToRoute(uri: String?): Route? = is NEmbed -> { if (LocalCache.getNoteIfExists(nip19.event.id) == null) { - LocalCache.justConsume(nip19.event, null) + LocalCache.justConsume(nip19.event, null, false) } Route.EventRedirect(nip19.event.id) } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/markdown/RenderContentAsMarkdown.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/markdown/RenderContentAsMarkdown.kt index b38b3a631..cc4f5356b 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/markdown/RenderContentAsMarkdown.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/markdown/RenderContentAsMarkdown.kt @@ -379,7 +379,7 @@ fun RenderContentAsMarkdownUserPreview() { ), ) - LocalCache.justConsume(qa, null) + LocalCache.justConsume(qa, null, false) } } @@ -428,7 +428,7 @@ fun RenderContentAsMarkdownNotePreview() { sig = "4c85e0eb0c46c5e3023431ad4ed8efa0abd66447ff757d246154e2349ac01ae0f88f213d02efa0a77f307f305d4a608c785ae1ca080c01cd3a9e7b8dffea6f9c", ) - LocalCache.justConsume(blogPost, null) + LocalCache.justConsume(blogPost, null, false) } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/PollNote.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/PollNote.kt index 10f98ee88..bca63658b 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/PollNote.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/PollNote.kt @@ -153,9 +153,9 @@ fun PollNotePreview() { runBlocking { withContext(Dispatchers.IO) { - LocalCache.justConsume(event, null) - LocalCache.consume(zapVote.zapRequest!!) - LocalCache.justConsume(zapVote, null) + LocalCache.justConsume(event, null, false) + LocalCache.consume(zapVote.zapRequest!!, null, false) + LocalCache.justConsume(zapVote, null, false) baseNote = LocalCache.getOrCreateNote("6ff9bc13d27490f6e3953325260bd996901a143de89886a0608c39e7d0160a72") } } @@ -207,7 +207,7 @@ fun PollNotePreview2() { runBlocking { withContext(Dispatchers.IO) { - LocalCache.justConsume(event, null) + LocalCache.justConsume(event, null, false) baseNote = LocalCache.getOrCreateNote("3064bf97800a4b04b612fc0fd498936eae75fffbdca5bbd09d19a6dc598530ab") } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/ZapTheDevsCard.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/ZapTheDevsCard.kt index 02728c85e..a4b257f7c 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/ZapTheDevsCard.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/ZapTheDevsCard.kt @@ -161,7 +161,7 @@ fun ZapTheDevsCardPreview() { } """.trimIndent() - LocalCache.justConsume(Event.fromJson(releaseNotes), null) + LocalCache.justConsume(Event.fromJson(releaseNotes), null, false) } val accountViewModel = mockAccountViewModel() diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/LiveActivity.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/LiveActivity.kt index b9638d112..853534e55 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/LiveActivity.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/LiveActivity.kt @@ -93,7 +93,7 @@ fun RenderLiveActivityEventPreview() { runBlocking { withContext(Dispatchers.IO) { - LocalCache.justConsume(event, null) + LocalCache.justConsume(event, null, false) baseNote = LocalCache.getOrCreateNote("19406ad34ce3c653d62eb73c1816ac27dcf473c2ccdccf5af7d90d2633c62561") } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Torrent.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Torrent.kt index bbb54e7dc..d8ebca375 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Torrent.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Torrent.kt @@ -126,7 +126,7 @@ fun TorrentPreview() { sig = "40e1ccfdc38a32e6c164bb66e50df0cd3769e0431137a07709534a72b462dfcbc40106560d0dd66841fef4cbb7aece7db64e83a0fbe414759d4d9a799e522c57", ) - LocalCache.justConsume(torrent, null) + LocalCache.justConsume(torrent, null, false) LocalCache.getOrCreateNote("e1ab66dd66e6ac4f32119deacf80d7c50787705d343d3bb896c099cf93821757") } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/TorrentComment.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/TorrentComment.kt index ce0ecc68e..80332b0ce 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/TorrentComment.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/TorrentComment.kt @@ -129,8 +129,8 @@ fun TorrentCommentPreview() { sig = "014391c310b1eebb807da4c9b11563126f2b795c9372a9432cae4dd2c0695b88584bb1c68814554c9b1a47626e3d60983e3653c29d0fdbc3a474277c140b95c3", ) - LocalCache.justConsume(torrent, null) - LocalCache.justConsume(comment, null) + LocalCache.justConsume(torrent, null, false) + LocalCache.justConsume(comment, null, false) LocalCache.getOrCreateNote("040aba32010b5adf7cb917054e894e86c8ea7a2bcee448b2266c493f3140e9a0") } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt index 907598faa..6fc5e8653 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt @@ -1085,7 +1085,7 @@ class AccountViewModel( var note = checkGetOrCreateNote(event.id) if (note == null) { - LocalCache.justConsume(event, null) + LocalCache.justConsume(event, null, false) note = checkGetOrCreateNote(event.id) } @@ -1469,7 +1469,7 @@ class AccountViewModel( // clear the encrypted payload to save memory LocalCache.getOrCreateNote(event.id).event = event.copyNoContent() - if (LocalCache.justConsume(it, null)) { + if (LocalCache.justConsume(it, null, false)) { unwrapIfNeeded(it, onReady) } } @@ -1483,7 +1483,7 @@ class AccountViewModel( if (existingNote != null) { unwrapIfNeeded(existingNote.event, onReady) } else { - if (LocalCache.justConsume(it, null)) { + if (LocalCache.justConsume(it, null, false)) { unwrapIfNeeded(it, onReady) } } @@ -1501,7 +1501,7 @@ class AccountViewModel( LocalCache.getOrCreateNote(event.id).event = event.copyNoContent() // this is not verifiable - if (LocalCache.justConsume(it, null)) { + if (LocalCache.justConsume(it, null, true)) { unwrapIfNeeded(it, onReady) } } @@ -1516,7 +1516,7 @@ class AccountViewModel( unwrapIfNeeded(existingNote.event, onReady) } else { // this is not verifiable - if (LocalCache.justConsume(it, null)) { + if (LocalCache.justConsume(it, null, true)) { unwrapIfNeeded(it, onReady) } } @@ -1686,7 +1686,7 @@ class AccountViewModel( ) } else { account.createZapRequestFor(toUserPubKeyHex, message, defaultZapType()) { zapRequest -> - LocalCache.justConsume(zapRequest, null) + LocalCache.justConsumeMyOwnEvent(zapRequest) LightningAddressResolver() .lnAddressInvoice( lnaddress, @@ -1766,7 +1766,7 @@ class AccountViewModel( val baseNote = LocalCache.getOrCreateNote(parsed.event) if (baseNote.event == null) { launch(Dispatchers.Default) { - LocalCache.justConsume(parsed.event, null) + LocalCache.justConsume(parsed.event, null, false) } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/PrecacheNewNotesProcessor.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/PrecacheNewNotesProcessor.kt index fdc392fd1..b3a15cb0e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/PrecacheNewNotesProcessor.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/PrecacheNewNotesProcessor.kt @@ -24,6 +24,7 @@ import android.util.Log import com.vitorpamplona.amethyst.Amethyst import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.LocalCache +import com.vitorpamplona.amethyst.model.LocalCache.indexDraftAsRealEvent import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.quartz.experimental.edits.PrivateOutboxRelayListEvent import com.vitorpamplona.quartz.nip01Core.core.Event @@ -69,7 +70,9 @@ class PrecacheNewNotesProcessor( is DraftEvent -> { // Avoid decrypting over and over again if the event already exist. if (!event.isDeleted() && event.preCachedDraft(account.signer) == null && event.pubKey == account.signer.pubKey) { - event.cachedDraft(account.signer) {} + event.cachedDraft(account.signer) { + cache.indexDraftAsRealEvent(event, it) + } } } @@ -80,7 +83,7 @@ class PrecacheNewNotesProcessor( event.unwrap(account.signer) { // clear the encrypted payload to save memory cache.getOrCreateNote(event.id).event = event.copyNoContent() - if (cache.justConsume(it, null)) { + if (cache.justConsume(it, null, false)) { cache.copyRelaysFromTo(publicNote, it) consumeAlreadyVerified(it, publicNote) } @@ -102,7 +105,8 @@ class PrecacheNewNotesProcessor( // clear the encrypted payload to save memory cache.getOrCreateNote(event.id).event = event.copyNoContent() - cache.justConsume(it, null) + // avoid verifying these events. + cache.justConsume(it, null, true) cache.copyRelaysFromTo(publicNote, it) } } else { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/threadview/ThreadFeedView.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/threadview/ThreadFeedView.kt index af5d6c517..b03bccab5 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/threadview/ThreadFeedView.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/threadview/ThreadFeedView.kt @@ -989,7 +989,7 @@ private fun RenderWikiHeaderForThreadPreview() { runBlocking { withContext(Dispatchers.IO) { - LocalCache.justConsume(event, null) + LocalCache.justConsume(event, null, false) } }