mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2025-03-28 18:51:45 +01:00
Adds a Bloom-based hint indexer with MurMur hash
This commit is contained in:
parent
94e0f4ed02
commit
aaf86bf53e
@ -75,11 +75,11 @@ import com.vitorpamplona.quartz.experimental.profileGallery.dimension
|
|||||||
import com.vitorpamplona.quartz.experimental.profileGallery.fromEvent
|
import com.vitorpamplona.quartz.experimental.profileGallery.fromEvent
|
||||||
import com.vitorpamplona.quartz.experimental.profileGallery.hash
|
import com.vitorpamplona.quartz.experimental.profileGallery.hash
|
||||||
import com.vitorpamplona.quartz.experimental.profileGallery.mimeType
|
import com.vitorpamplona.quartz.experimental.profileGallery.mimeType
|
||||||
import com.vitorpamplona.quartz.nip01Core.EventHintBundle
|
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.hexToByteArray
|
import com.vitorpamplona.quartz.nip01Core.core.hexToByteArray
|
||||||
import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair
|
import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
|
||||||
import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper
|
import com.vitorpamplona.quartz.nip01Core.jackson.EventMapper
|
||||||
import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent
|
import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent
|
||||||
import com.vitorpamplona.quartz.nip01Core.signers.EventTemplate
|
import com.vitorpamplona.quartz.nip01Core.signers.EventTemplate
|
||||||
|
@ -40,10 +40,10 @@ import com.vitorpamplona.ammolite.relays.filters.EOSETime
|
|||||||
import com.vitorpamplona.quartz.experimental.bounties.addedRewardValue
|
import com.vitorpamplona.quartz.experimental.bounties.addedRewardValue
|
||||||
import com.vitorpamplona.quartz.experimental.bounties.hasAdditionalReward
|
import com.vitorpamplona.quartz.experimental.bounties.hasAdditionalReward
|
||||||
import com.vitorpamplona.quartz.lightning.LnInvoiceUtil
|
import com.vitorpamplona.quartz.lightning.LnInvoiceUtil
|
||||||
import com.vitorpamplona.quartz.nip01Core.EventHintBundle
|
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.AddressableEvent
|
import com.vitorpamplona.quartz.nip01Core.core.AddressableEvent
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
|
||||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
|
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
|
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.Address
|
import com.vitorpamplona.quartz.nip01Core.tags.addressables.Address
|
||||||
|
@ -26,7 +26,7 @@ import androidx.lifecycle.ViewModel
|
|||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.vitorpamplona.amethyst.model.Account
|
import com.vitorpamplona.amethyst.model.Account
|
||||||
import com.vitorpamplona.amethyst.model.PublicChatChannel
|
import com.vitorpamplona.amethyst.model.PublicChatChannel
|
||||||
import com.vitorpamplona.quartz.nip01Core.EventHintBundle
|
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
||||||
import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelCreateEvent
|
import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelCreateEvent
|
||||||
import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelMetadataEvent
|
import com.vitorpamplona.quartz.nip28PublicChat.admin.ChannelMetadataEvent
|
||||||
|
@ -66,10 +66,10 @@ import com.vitorpamplona.quartz.experimental.zapPolls.consensusThreshold
|
|||||||
import com.vitorpamplona.quartz.experimental.zapPolls.maxAmount
|
import com.vitorpamplona.quartz.experimental.zapPolls.maxAmount
|
||||||
import com.vitorpamplona.quartz.experimental.zapPolls.minAmount
|
import com.vitorpamplona.quartz.experimental.zapPolls.minAmount
|
||||||
import com.vitorpamplona.quartz.experimental.zapPolls.tags.PollOptionTag
|
import com.vitorpamplona.quartz.experimental.zapPolls.tags.PollOptionTag
|
||||||
import com.vitorpamplona.quartz.nip01Core.EventHintBundle
|
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.AddressableEvent
|
import com.vitorpamplona.quartz.nip01Core.core.AddressableEvent
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.events.eTags
|
import com.vitorpamplona.quartz.nip01Core.tags.events.eTags
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.geohash.geohash
|
import com.vitorpamplona.quartz.nip01Core.tags.geohash.geohash
|
||||||
|
@ -165,7 +165,7 @@ import com.vitorpamplona.amethyst.ui.theme.ZeroPadding
|
|||||||
import com.vitorpamplona.amethyst.ui.theme.innerPostModifier
|
import com.vitorpamplona.amethyst.ui.theme.innerPostModifier
|
||||||
import com.vitorpamplona.amethyst.ui.theme.liveStreamTag
|
import com.vitorpamplona.amethyst.ui.theme.liveStreamTag
|
||||||
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
||||||
import com.vitorpamplona.quartz.nip01Core.EventHintBundle
|
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.events.isTaggedEvent
|
import com.vitorpamplona.quartz.nip01Core.tags.events.isTaggedEvent
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.hashtags.hasHashtags
|
import com.vitorpamplona.quartz.nip01Core.tags.hashtags.hasHashtags
|
||||||
|
@ -0,0 +1,135 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2024 Vitor Pamplona
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to use,
|
||||||
|
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||||
|
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||||
|
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.vitorpamplona.quartz.benchmark
|
||||||
|
|
||||||
|
import androidx.benchmark.junit4.BenchmarkRule
|
||||||
|
import androidx.benchmark.junit4.measureRepeated
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.core.hexToByteArray
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.hints.bloom.BloomFilterMurMur3
|
||||||
|
import com.vitorpamplona.quartz.utils.RandomInstance
|
||||||
|
import org.junit.Rule
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class BloomFilterMurMur3Benchmark {
|
||||||
|
@get:Rule val benchmarkRule = BenchmarkRule()
|
||||||
|
|
||||||
|
val testEncoded = "100:10:AKiEIEQKALgRACEABA==:3"
|
||||||
|
|
||||||
|
val key1 = "ca29c211f1c72d5b6622268ff43d2288ea2b2cb5b9aa196ff9f1704fc914b71b".hexToByteArray()
|
||||||
|
val key2 = "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c".hexToByteArray()
|
||||||
|
val key3 = "560c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c".hexToByteArray()
|
||||||
|
|
||||||
|
val keys =
|
||||||
|
mutableListOf<ByteArray>().apply {
|
||||||
|
for (seed in 0..1000000) {
|
||||||
|
add(RandomInstance.bytes(32))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val keys2 =
|
||||||
|
mutableListOf<ByteArray>().apply {
|
||||||
|
for (seed in 0..1000000) {
|
||||||
|
add(RandomInstance.bytes(32))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun addExisting() {
|
||||||
|
val filter = BloomFilterMurMur3.decode(testEncoded)
|
||||||
|
benchmarkRule.measureRepeated {
|
||||||
|
filter.add(key1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun addNew() {
|
||||||
|
val filter = BloomFilterMurMur3.decode(testEncoded)
|
||||||
|
benchmarkRule.measureRepeated {
|
||||||
|
filter.add(key3)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun mightContainTrue() {
|
||||||
|
val filter = BloomFilterMurMur3(10_000_000, 5)
|
||||||
|
filter.add(key1)
|
||||||
|
keys.forEach(filter::add)
|
||||||
|
benchmarkRule.measureRepeated {
|
||||||
|
filter.mightContain(key1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun mightContainFalse() {
|
||||||
|
val filter = BloomFilterMurMur3(10_000_000, 5)
|
||||||
|
keys.forEach(filter::add)
|
||||||
|
benchmarkRule.measureRepeated {
|
||||||
|
filter.mightContain(key3)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun decode() {
|
||||||
|
benchmarkRule.measureRepeated {
|
||||||
|
BloomFilterMurMur3.decode(testEncoded)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun encode() {
|
||||||
|
val filter = BloomFilterMurMur3.decode(testEncoded)
|
||||||
|
benchmarkRule.measureRepeated {
|
||||||
|
filter.encode()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun largeFilterBuild() {
|
||||||
|
val bloomFilter = BloomFilterMurMur3(10_000_000, 5)
|
||||||
|
|
||||||
|
benchmarkRule.measureRepeated {
|
||||||
|
keys.forEach(bloomFilter::add)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun largeFilterCheckExisting() {
|
||||||
|
val bloomFilter = BloomFilterMurMur3(10_000_000, 5)
|
||||||
|
keys.forEach(bloomFilter::add)
|
||||||
|
|
||||||
|
benchmarkRule.measureRepeated {
|
||||||
|
keys.forEach(bloomFilter::mightContain)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun largeFilterCheckNew() {
|
||||||
|
val bloomFilter = BloomFilterMurMur3(10_000_000, 5)
|
||||||
|
keys.forEach(bloomFilter::add)
|
||||||
|
|
||||||
|
benchmarkRule.measureRepeated {
|
||||||
|
keys2.forEach(bloomFilter::mightContain)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,88 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2024 Vitor Pamplona
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to use,
|
||||||
|
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||||
|
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||||
|
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.vitorpamplona.quartz.benchmark
|
||||||
|
|
||||||
|
import androidx.benchmark.junit4.BenchmarkRule
|
||||||
|
import androidx.benchmark.junit4.measureRepeated
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.hints.HintIndexer
|
||||||
|
import com.vitorpamplona.quartz.utils.RandomInstance
|
||||||
|
import org.junit.Rule
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
import java.nio.charset.Charset
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class HintIndexerBenchmark {
|
||||||
|
@get:Rule val benchmarkRule = BenchmarkRule()
|
||||||
|
|
||||||
|
val keys =
|
||||||
|
mutableListOf<ByteArray>().apply {
|
||||||
|
for (seed in 0..1_000_000) {
|
||||||
|
add(RandomInstance.bytes(32))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val relays =
|
||||||
|
getInstrumentation()
|
||||||
|
.context.assets
|
||||||
|
.open("relayDB.txt")
|
||||||
|
.readBytes()
|
||||||
|
.toString(Charset.forName("utf-8"))
|
||||||
|
.split("\n")
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun relayUriHashcode() {
|
||||||
|
benchmarkRule.measureRepeated {
|
||||||
|
"wss://relay.bitcoin.social".hashCode()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun getRelayHints() {
|
||||||
|
val indexer = HintIndexer()
|
||||||
|
|
||||||
|
keys.forEach { key ->
|
||||||
|
(0..5).map {
|
||||||
|
indexer.index(key, relays.random())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val key = keys.random()
|
||||||
|
|
||||||
|
benchmarkRule.measureRepeated {
|
||||||
|
indexer.get(key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun buildIndexer() {
|
||||||
|
benchmarkRule.measureRepeated {
|
||||||
|
val indexer = HintIndexer()
|
||||||
|
keys.forEach { key ->
|
||||||
|
(0..5).map {
|
||||||
|
indexer.index(key, relays.random())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
2539
quartz/src/androidTest/assets/relayDB.txt
Normal file
2539
quartz/src/androidTest/assets/relayDB.txt
Normal file
File diff suppressed because it is too large
Load Diff
@ -49,13 +49,12 @@ class BloomFilter(
|
|||||||
|
|
||||||
fun add(value: HexKey) = add(value.hexToByteArray())
|
fun add(value: HexKey) = add(value.hexToByteArray())
|
||||||
|
|
||||||
fun print(): String {
|
fun print() =
|
||||||
val builder = StringBuilder()
|
buildString {
|
||||||
for (seed in 0 until bits.size()) {
|
for (seed in 0 until bits.size()) {
|
||||||
builder.append(if (bits.get(seed)) "1" else "0")
|
append(if (bits.get(seed)) "1" else "0")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return builder.toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun add(value: ByteArray) {
|
fun add(value: ByteArray) {
|
||||||
lock.write {
|
lock.write {
|
||||||
|
@ -20,8 +20,8 @@
|
|||||||
*/
|
*/
|
||||||
package com.vitorpamplona.quartz.experimental.bounties
|
package com.vitorpamplona.quartz.experimental.bounties
|
||||||
|
|
||||||
import com.vitorpamplona.quartz.nip01Core.EventHintBundle
|
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
|
||||||
import com.vitorpamplona.quartz.nip01Core.signers.EventTemplate
|
import com.vitorpamplona.quartz.nip01Core.signers.EventTemplate
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.hashtags.hashtag
|
import com.vitorpamplona.quartz.nip01Core.tags.hashtags.hashtag
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.people.PTag
|
import com.vitorpamplona.quartz.nip01Core.tags.people.PTag
|
||||||
|
@ -22,11 +22,11 @@ package com.vitorpamplona.quartz.experimental.nip95.header
|
|||||||
|
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import com.vitorpamplona.quartz.experimental.nip95.data.FileStorageEvent
|
import com.vitorpamplona.quartz.experimental.nip95.data.FileStorageEvent
|
||||||
import com.vitorpamplona.quartz.nip01Core.EventHintBundle
|
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.any
|
import com.vitorpamplona.quartz.nip01Core.core.any
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
|
||||||
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.events.eTag
|
import com.vitorpamplona.quartz.nip01Core.tags.events.eTag
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
package com.vitorpamplona.quartz.nip01Core
|
package com.vitorpamplona.quartz.nip01Core.hints
|
||||||
|
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
import com.vitorpamplona.quartz.nip01Core.core.Event
|
@ -0,0 +1,49 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2024 Vitor Pamplona
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to use,
|
||||||
|
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||||
|
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||||
|
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.vitorpamplona.quartz.nip01Core.hints
|
||||||
|
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.hints.bloom.BloomFilterMurMur3
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instead of having one bloom filter per relay, which could create many
|
||||||
|
* large filters for very few events, this class uses only one mega bloom
|
||||||
|
* filter and uses the hashcode of the relay uri as differentiator in salt.
|
||||||
|
*/
|
||||||
|
class HintIndexer(
|
||||||
|
size: Int = 10_000_000,
|
||||||
|
rounds: Int = 5,
|
||||||
|
) {
|
||||||
|
private val bloomFilter = BloomFilterMurMur3(size, rounds)
|
||||||
|
private val relayDB = hashSetOf<String>()
|
||||||
|
|
||||||
|
fun index(
|
||||||
|
id: ByteArray,
|
||||||
|
relay: String,
|
||||||
|
) {
|
||||||
|
relayDB.add(relay)
|
||||||
|
bloomFilter.add(id, relay.hashCode())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun get(id: ByteArray): List<String> =
|
||||||
|
relayDB.filter {
|
||||||
|
bloomFilter.mightContain(id, it.hashCode())
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2024 Vitor Pamplona
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to use,
|
||||||
|
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||||
|
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||||
|
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.vitorpamplona.quartz.nip01Core.hints
|
||||||
|
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.hints.types.AddressHint
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.hints.types.EventIdHint
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.hints.types.PubKeyHint
|
||||||
|
|
||||||
|
interface HintProvider {
|
||||||
|
fun eventHints(): EventIdHint
|
||||||
|
|
||||||
|
fun addressIdHints(): AddressHint
|
||||||
|
|
||||||
|
fun pubKeyHints(): PubKeyHint
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2024 Vitor Pamplona
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to use,
|
||||||
|
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||||
|
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||||
|
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.vitorpamplona.quartz.nip01Core.hints.bloom
|
||||||
|
|
||||||
|
import java.util.BitSet
|
||||||
|
|
||||||
|
fun BitSet.printBits() =
|
||||||
|
buildString {
|
||||||
|
for (seed in 0 until size()) {
|
||||||
|
append(if (this@printBits.get(seed)) "1" else "0")
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,83 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2024 Vitor Pamplona
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to use,
|
||||||
|
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||||
|
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||||
|
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.vitorpamplona.quartz.nip01Core.hints.bloom
|
||||||
|
|
||||||
|
import com.vitorpamplona.quartz.utils.RandomInstance
|
||||||
|
import java.util.Base64
|
||||||
|
import java.util.BitSet
|
||||||
|
import java.util.concurrent.locks.ReentrantReadWriteLock
|
||||||
|
import kotlin.concurrent.read
|
||||||
|
import kotlin.concurrent.write
|
||||||
|
|
||||||
|
class BloomFilterMurMur3(
|
||||||
|
private val size: Int,
|
||||||
|
private val rounds: Int,
|
||||||
|
private val bits: BitSet = BitSet(size),
|
||||||
|
private val commonSalt: Int = RandomInstance.int(),
|
||||||
|
) {
|
||||||
|
private val hasher = MurmurHash3()
|
||||||
|
private val lock = ReentrantReadWriteLock()
|
||||||
|
|
||||||
|
fun add(
|
||||||
|
value: ByteArray,
|
||||||
|
salt: Int = commonSalt,
|
||||||
|
) {
|
||||||
|
lock.write {
|
||||||
|
repeat(rounds) {
|
||||||
|
bits.set(hash(value, salt + it))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun mightContain(
|
||||||
|
value: ByteArray,
|
||||||
|
salt: Int = commonSalt,
|
||||||
|
): Boolean {
|
||||||
|
lock.read {
|
||||||
|
repeat(rounds) {
|
||||||
|
if (!bits.get(hash(value, salt + it))) return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun hash(
|
||||||
|
value: ByteArray,
|
||||||
|
seed: Int,
|
||||||
|
) = hasher.hash(value, seed).mod(size)
|
||||||
|
|
||||||
|
fun encode() = encode(this)
|
||||||
|
|
||||||
|
fun printBits() = bits.printBits()
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun encode(f: BloomFilterMurMur3): String {
|
||||||
|
val bitSetB64 = Base64.getEncoder().encodeToString(f.bits.toByteArray())
|
||||||
|
return "${f.size}:${f.rounds}:$bitSetB64:${f.commonSalt}"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun decode(encodedStr: String): BloomFilterMurMur3 {
|
||||||
|
val (sizeStr, roundsStr, filterB64, salt) = encodedStr.split(":")
|
||||||
|
val bitSet = BitSet.valueOf(Base64.getDecoder().decode(filterB64))
|
||||||
|
return BloomFilterMurMur3(sizeStr.toInt(), roundsStr.toInt(), bitSet, salt.toInt())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,121 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2024 Vitor Pamplona
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to use,
|
||||||
|
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||||
|
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||||
|
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.vitorpamplona.quartz.nip01Core.hints.bloom
|
||||||
|
|
||||||
|
class MurmurHash3 {
|
||||||
|
fun hash(
|
||||||
|
data: ByteArray,
|
||||||
|
seed: Int,
|
||||||
|
) = hash(data, 0, data.size, seed)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates 32 bit hash .
|
||||||
|
* @param data the byte array to hash
|
||||||
|
* @param offset the start offset of the data in the array (always 0)
|
||||||
|
* @param length the length of the data in the array
|
||||||
|
* @param seed the seed for the hash (int)
|
||||||
|
* @return 32 bit hash of the given array
|
||||||
|
*/
|
||||||
|
fun hash(
|
||||||
|
data: ByteArray,
|
||||||
|
offset: Int,
|
||||||
|
length: Int,
|
||||||
|
seed: Int,
|
||||||
|
): Int {
|
||||||
|
val c1 = -0x3361d2af // 0xcc9e2d51
|
||||||
|
val c2 = 0x1b873593
|
||||||
|
var h1 = seed
|
||||||
|
val roundedEnd = offset + (length and 0xFFFFFFFC.toInt()) // Round down to 4-byte blocks
|
||||||
|
|
||||||
|
var i = offset
|
||||||
|
while (i < roundedEnd) {
|
||||||
|
var k1 =
|
||||||
|
(data[i].toInt() and 0xFF) or
|
||||||
|
((data[i + 1].toInt() and 0xFF) shl 8) or
|
||||||
|
((data[i + 2].toInt() and 0xFF) shl 16) or
|
||||||
|
((data[i + 3].toInt() and 0xFF) shl 24)
|
||||||
|
|
||||||
|
i += 4
|
||||||
|
|
||||||
|
k1 *= c1
|
||||||
|
k1 = Integer.rotateLeft(k1, 15)
|
||||||
|
k1 *= c2
|
||||||
|
|
||||||
|
h1 = h1 xor k1
|
||||||
|
h1 = Integer.rotateLeft(h1, 13)
|
||||||
|
h1 = h1 * 5 + -0x19ab949c // 0xe6546b64
|
||||||
|
}
|
||||||
|
|
||||||
|
// processing tail (remaining bytes)
|
||||||
|
var k1 = 0
|
||||||
|
when (length and 3) {
|
||||||
|
3 -> {
|
||||||
|
k1 = k1 or ((data[i + 2].toInt() and 0xFF) shl 16)
|
||||||
|
k1 = k1 or ((data[i + 1].toInt() and 0xFF) shl 8)
|
||||||
|
k1 = k1 or (data[i].toInt() and 0xFF)
|
||||||
|
|
||||||
|
k1 *= c1
|
||||||
|
k1 = Integer.rotateLeft(k1, 15)
|
||||||
|
k1 *= c2
|
||||||
|
|
||||||
|
h1 = h1 xor k1
|
||||||
|
}
|
||||||
|
|
||||||
|
2 -> {
|
||||||
|
k1 = k1 or (data[i + 1].toInt() and 0xFF shl 8)
|
||||||
|
k1 = k1 or (data[i].toInt() and 0xFF)
|
||||||
|
|
||||||
|
k1 *= c1
|
||||||
|
k1 = Integer.rotateLeft(k1, 15)
|
||||||
|
k1 *= c2
|
||||||
|
|
||||||
|
h1 = h1 xor k1
|
||||||
|
}
|
||||||
|
|
||||||
|
1 -> {
|
||||||
|
k1 = k1 or (data[i].toInt() and 0xFF)
|
||||||
|
|
||||||
|
k1 *= c1
|
||||||
|
k1 = Integer.rotateLeft(k1, 15)
|
||||||
|
k1 *= c2
|
||||||
|
|
||||||
|
h1 = h1 xor k1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// final mix
|
||||||
|
h1 = h1 xor length
|
||||||
|
h1 = fmix32(h1)
|
||||||
|
|
||||||
|
return h1
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun fmix32(h: Int): Int {
|
||||||
|
var f = h
|
||||||
|
f = f xor (f ushr 16)
|
||||||
|
f *= -0x7a143595 // 0x85ebca6b
|
||||||
|
f = f xor (f ushr 13)
|
||||||
|
f *= -0x3d4d51cb // 0xc2b2ae35
|
||||||
|
f = f xor (f ushr 16)
|
||||||
|
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2024 Vitor Pamplona
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to use,
|
||||||
|
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||||
|
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||||
|
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.vitorpamplona.quartz.nip01Core.hints.types
|
||||||
|
|
||||||
|
class AddressHint(
|
||||||
|
val addressId: String,
|
||||||
|
var relay: String? = null,
|
||||||
|
) : Hint {
|
||||||
|
override fun id() = addressId.toByteArray(Charsets.UTF_8)
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2024 Vitor Pamplona
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to use,
|
||||||
|
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||||
|
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||||
|
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.vitorpamplona.quartz.nip01Core.hints.types
|
||||||
|
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.core.hexToByteArray
|
||||||
|
|
||||||
|
class EventIdHint(
|
||||||
|
val eventId: HexKey,
|
||||||
|
var relay: String? = null,
|
||||||
|
) : Hint {
|
||||||
|
override fun id() = eventId.hexToByteArray()
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2024 Vitor Pamplona
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to use,
|
||||||
|
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||||
|
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||||
|
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.vitorpamplona.quartz.nip01Core.hints.types
|
||||||
|
|
||||||
|
interface Hint {
|
||||||
|
fun id(): ByteArray
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2024 Vitor Pamplona
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to use,
|
||||||
|
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||||
|
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||||
|
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.vitorpamplona.quartz.nip01Core.hints.types
|
||||||
|
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.core.hexToByteArray
|
||||||
|
|
||||||
|
class PubKeyHint(
|
||||||
|
val pubkey: HexKey,
|
||||||
|
var relay: String? = null,
|
||||||
|
) : Hint {
|
||||||
|
override fun id() = pubkey.hexToByteArray()
|
||||||
|
}
|
@ -21,11 +21,11 @@
|
|||||||
package com.vitorpamplona.quartz.nip03Timestamp
|
package com.vitorpamplona.quartz.nip03Timestamp
|
||||||
|
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import com.vitorpamplona.quartz.nip01Core.EventHintBundle
|
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.hexToByteArray
|
import com.vitorpamplona.quartz.nip01Core.core.hexToByteArray
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
|
||||||
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.events.eTag
|
import com.vitorpamplona.quartz.nip01Core.tags.events.eTag
|
||||||
|
@ -20,8 +20,8 @@
|
|||||||
*/
|
*/
|
||||||
package com.vitorpamplona.quartz.nip04Dm.messages
|
package com.vitorpamplona.quartz.nip04Dm.messages
|
||||||
|
|
||||||
import com.vitorpamplona.quartz.nip01Core.EventHintBundle
|
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.events.EventReference
|
import com.vitorpamplona.quartz.nip01Core.tags.events.EventReference
|
||||||
import com.vitorpamplona.quartz.nip10Notes.tags.MarkedETag
|
import com.vitorpamplona.quartz.nip10Notes.tags.MarkedETag
|
||||||
|
|
||||||
|
@ -21,9 +21,9 @@
|
|||||||
package com.vitorpamplona.quartz.nip10Notes
|
package com.vitorpamplona.quartz.nip10Notes
|
||||||
|
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import com.vitorpamplona.quartz.nip01Core.EventHintBundle
|
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
|
||||||
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
||||||
import com.vitorpamplona.quartz.nip10Notes.tags.markedETags
|
import com.vitorpamplona.quartz.nip10Notes.tags.markedETags
|
||||||
import com.vitorpamplona.quartz.nip10Notes.tags.prepareETagsAsReplyTo
|
import com.vitorpamplona.quartz.nip10Notes.tags.prepareETagsAsReplyTo
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.vitorpamplona.quartz.nip10Notes.tags
|
package com.vitorpamplona.quartz.nip10Notes.tags
|
||||||
|
|
||||||
import com.vitorpamplona.quartz.nip01Core.EventHintBundle
|
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
|
||||||
import com.vitorpamplona.quartz.nip10Notes.BaseThreadedEvent
|
import com.vitorpamplona.quartz.nip10Notes.BaseThreadedEvent
|
||||||
import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent
|
import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent
|
||||||
|
|
||||||
|
@ -20,9 +20,9 @@
|
|||||||
*/
|
*/
|
||||||
package com.vitorpamplona.quartz.nip17Dm
|
package com.vitorpamplona.quartz.nip17Dm
|
||||||
|
|
||||||
import com.vitorpamplona.quartz.nip01Core.EventHintBundle
|
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
|
||||||
import com.vitorpamplona.quartz.nip01Core.signers.EventTemplate
|
import com.vitorpamplona.quartz.nip01Core.signers.EventTemplate
|
||||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
|
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
|
||||||
import com.vitorpamplona.quartz.nip17Dm.files.ChatMessageEncryptedFileHeaderEvent
|
import com.vitorpamplona.quartz.nip17Dm.files.ChatMessageEncryptedFileHeaderEvent
|
||||||
|
@ -21,9 +21,9 @@
|
|||||||
package com.vitorpamplona.quartz.nip17Dm.files
|
package com.vitorpamplona.quartz.nip17Dm.files
|
||||||
|
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import com.vitorpamplona.quartz.nip01Core.EventHintBundle
|
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
|
||||||
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.people.PTag
|
import com.vitorpamplona.quartz.nip01Core.tags.people.PTag
|
||||||
|
@ -20,9 +20,9 @@
|
|||||||
*/
|
*/
|
||||||
package com.vitorpamplona.quartz.nip17Dm.files
|
package com.vitorpamplona.quartz.nip17Dm.files
|
||||||
|
|
||||||
import com.vitorpamplona.quartz.nip01Core.EventHintBundle
|
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.people.PTag
|
import com.vitorpamplona.quartz.nip01Core.tags.people.PTag
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.people.pTag
|
import com.vitorpamplona.quartz.nip01Core.tags.people.pTag
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.people.pTags
|
import com.vitorpamplona.quartz.nip01Core.tags.people.pTags
|
||||||
|
@ -21,9 +21,9 @@
|
|||||||
package com.vitorpamplona.quartz.nip17Dm.messages
|
package com.vitorpamplona.quartz.nip17Dm.messages
|
||||||
|
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import com.vitorpamplona.quartz.nip01Core.EventHintBundle
|
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
|
||||||
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.people.PTag
|
import com.vitorpamplona.quartz.nip01Core.tags.people.PTag
|
||||||
|
@ -20,8 +20,8 @@
|
|||||||
*/
|
*/
|
||||||
package com.vitorpamplona.quartz.nip17Dm.messages
|
package com.vitorpamplona.quartz.nip17Dm.messages
|
||||||
|
|
||||||
import com.vitorpamplona.quartz.nip01Core.EventHintBundle
|
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.people.PTag
|
import com.vitorpamplona.quartz.nip01Core.tags.people.PTag
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.people.pTag
|
import com.vitorpamplona.quartz.nip01Core.tags.people.pTag
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.people.pTags
|
import com.vitorpamplona.quartz.nip01Core.tags.people.pTags
|
||||||
|
@ -20,8 +20,8 @@
|
|||||||
*/
|
*/
|
||||||
package com.vitorpamplona.quartz.nip21UriScheme
|
package com.vitorpamplona.quartz.nip21UriScheme
|
||||||
|
|
||||||
import com.vitorpamplona.quartz.nip01Core.EventHintBundle
|
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
|
||||||
import com.vitorpamplona.quartz.nip19Bech32.toNIP19
|
import com.vitorpamplona.quartz.nip19Bech32.toNIP19
|
||||||
|
|
||||||
fun Event.toNostrUri(): String = "nostr:${toNIP19()}"
|
fun Event.toNostrUri(): String = "nostr:${toNIP19()}"
|
||||||
|
@ -21,11 +21,11 @@
|
|||||||
package com.vitorpamplona.quartz.nip22Comments
|
package com.vitorpamplona.quartz.nip22Comments
|
||||||
|
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import com.vitorpamplona.quartz.nip01Core.EventHintBundle
|
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.AddressableEvent
|
import com.vitorpamplona.quartz.nip01Core.core.AddressableEvent
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
|
||||||
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
||||||
import com.vitorpamplona.quartz.nip10Notes.BaseThreadedEvent
|
import com.vitorpamplona.quartz.nip10Notes.BaseThreadedEvent
|
||||||
import com.vitorpamplona.quartz.nip21UriScheme.toNostrUri
|
import com.vitorpamplona.quartz.nip21UriScheme.toNostrUri
|
||||||
|
@ -21,10 +21,10 @@
|
|||||||
package com.vitorpamplona.quartz.nip25Reactions
|
package com.vitorpamplona.quartz.nip25Reactions
|
||||||
|
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import com.vitorpamplona.quartz.nip01Core.EventHintBundle
|
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.AddressableEvent
|
import com.vitorpamplona.quartz.nip01Core.core.AddressableEvent
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
|
||||||
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.aTag
|
import com.vitorpamplona.quartz.nip01Core.tags.addressables.aTag
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
||||||
|
@ -21,9 +21,9 @@
|
|||||||
package com.vitorpamplona.quartz.nip28PublicChat.admin
|
package com.vitorpamplona.quartz.nip28PublicChat.admin
|
||||||
|
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import com.vitorpamplona.quartz.nip01Core.EventHintBundle
|
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
|
||||||
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.events.eTags
|
import com.vitorpamplona.quartz.nip01Core.tags.events.eTags
|
||||||
|
@ -21,9 +21,9 @@
|
|||||||
package com.vitorpamplona.quartz.nip28PublicChat.admin
|
package com.vitorpamplona.quartz.nip28PublicChat.admin
|
||||||
|
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import com.vitorpamplona.quartz.nip01Core.EventHintBundle
|
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
|
||||||
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
||||||
import com.vitorpamplona.quartz.nip28PublicChat.base.BasePublicChatEvent
|
import com.vitorpamplona.quartz.nip28PublicChat.base.BasePublicChatEvent
|
||||||
|
@ -21,9 +21,9 @@
|
|||||||
package com.vitorpamplona.quartz.nip28PublicChat.admin
|
package com.vitorpamplona.quartz.nip28PublicChat.admin
|
||||||
|
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import com.vitorpamplona.quartz.nip01Core.EventHintBundle
|
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
|
||||||
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.people.PTag
|
import com.vitorpamplona.quartz.nip01Core.tags.people.PTag
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.people.pTags
|
import com.vitorpamplona.quartz.nip01Core.tags.people.pTags
|
||||||
|
@ -20,8 +20,8 @@
|
|||||||
*/
|
*/
|
||||||
package com.vitorpamplona.quartz.nip28PublicChat.base
|
package com.vitorpamplona.quartz.nip28PublicChat.base
|
||||||
|
|
||||||
import com.vitorpamplona.quartz.nip01Core.EventHintBundle
|
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.people.PTag
|
import com.vitorpamplona.quartz.nip01Core.tags.people.PTag
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.people.pTag
|
import com.vitorpamplona.quartz.nip01Core.tags.people.pTag
|
||||||
|
@ -21,9 +21,9 @@
|
|||||||
package com.vitorpamplona.quartz.nip28PublicChat.message
|
package com.vitorpamplona.quartz.nip28PublicChat.message
|
||||||
|
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import com.vitorpamplona.quartz.nip01Core.EventHintBundle
|
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
|
||||||
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
||||||
import com.vitorpamplona.quartz.nip10Notes.BaseThreadedEvent
|
import com.vitorpamplona.quartz.nip10Notes.BaseThreadedEvent
|
||||||
|
@ -21,10 +21,10 @@
|
|||||||
package com.vitorpamplona.quartz.nip30CustomEmoji.selection
|
package com.vitorpamplona.quartz.nip30CustomEmoji.selection
|
||||||
|
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import com.vitorpamplona.quartz.nip01Core.EventHintBundle
|
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.BaseReplaceableEvent
|
import com.vitorpamplona.quartz.nip01Core.core.BaseReplaceableEvent
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
|
||||||
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
||||||
import com.vitorpamplona.quartz.nip01Core.signers.eventUpdate
|
import com.vitorpamplona.quartz.nip01Core.signers.eventUpdate
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.Address
|
import com.vitorpamplona.quartz.nip01Core.tags.addressables.Address
|
||||||
|
@ -21,9 +21,9 @@
|
|||||||
package com.vitorpamplona.quartz.nip34Git.issue
|
package com.vitorpamplona.quartz.nip34Git.issue
|
||||||
|
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import com.vitorpamplona.quartz.nip01Core.EventHintBundle
|
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
|
||||||
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
|
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.hashtags.hashtags
|
import com.vitorpamplona.quartz.nip01Core.tags.hashtags.hashtags
|
||||||
|
@ -20,8 +20,8 @@
|
|||||||
*/
|
*/
|
||||||
package com.vitorpamplona.quartz.nip34Git.issue
|
package com.vitorpamplona.quartz.nip34Git.issue
|
||||||
|
|
||||||
import com.vitorpamplona.quartz.nip01Core.EventHintBundle
|
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
|
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.people.PTag
|
import com.vitorpamplona.quartz.nip01Core.tags.people.PTag
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.people.pTags
|
import com.vitorpamplona.quartz.nip01Core.tags.people.pTags
|
||||||
|
@ -21,9 +21,9 @@
|
|||||||
package com.vitorpamplona.quartz.nip34Git.reply
|
package com.vitorpamplona.quartz.nip34Git.reply
|
||||||
|
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import com.vitorpamplona.quartz.nip01Core.EventHintBundle
|
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
|
||||||
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
|
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
|
||||||
import com.vitorpamplona.quartz.nip10Notes.BaseThreadedEvent
|
import com.vitorpamplona.quartz.nip10Notes.BaseThreadedEvent
|
||||||
|
@ -20,8 +20,8 @@
|
|||||||
*/
|
*/
|
||||||
package com.vitorpamplona.quartz.nip34Git.reply
|
package com.vitorpamplona.quartz.nip34Git.reply
|
||||||
|
|
||||||
import com.vitorpamplona.quartz.nip01Core.EventHintBundle
|
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
|
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.people.PTag
|
import com.vitorpamplona.quartz.nip01Core.tags.people.PTag
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.people.pTags
|
import com.vitorpamplona.quartz.nip01Core.tags.people.pTags
|
||||||
|
@ -21,9 +21,9 @@
|
|||||||
package com.vitorpamplona.quartz.nip35Torrents
|
package com.vitorpamplona.quartz.nip35Torrents
|
||||||
|
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import com.vitorpamplona.quartz.nip01Core.EventHintBundle
|
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
|
||||||
import com.vitorpamplona.quartz.nip01Core.signers.EventTemplate
|
import com.vitorpamplona.quartz.nip01Core.signers.EventTemplate
|
||||||
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
||||||
|
@ -21,9 +21,9 @@
|
|||||||
package com.vitorpamplona.quartz.nip53LiveActivities.chat
|
package com.vitorpamplona.quartz.nip53LiveActivities.chat
|
||||||
|
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import com.vitorpamplona.quartz.nip01Core.EventHintBundle
|
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
|
||||||
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
|
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
|
||||||
import com.vitorpamplona.quartz.nip10Notes.BaseThreadedEvent
|
import com.vitorpamplona.quartz.nip10Notes.BaseThreadedEvent
|
||||||
|
@ -20,8 +20,8 @@
|
|||||||
*/
|
*/
|
||||||
package com.vitorpamplona.quartz.nip53LiveActivities.chat
|
package com.vitorpamplona.quartz.nip53LiveActivities.chat
|
||||||
|
|
||||||
import com.vitorpamplona.quartz.nip01Core.EventHintBundle
|
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
|
import com.vitorpamplona.quartz.nip01Core.tags.addressables.ATag
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.people.PTag
|
import com.vitorpamplona.quartz.nip01Core.tags.people.PTag
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.people.pTag
|
import com.vitorpamplona.quartz.nip01Core.tags.people.pTag
|
||||||
|
@ -22,10 +22,10 @@ package com.vitorpamplona.quartz.nip72ModCommunities.approval
|
|||||||
|
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import com.vitorpamplona.quartz.nip01Core.EventHintBundle
|
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
|
||||||
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.taggedATags
|
import com.vitorpamplona.quartz.nip01Core.tags.addressables.taggedATags
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.addressables.taggedAddresses
|
import com.vitorpamplona.quartz.nip01Core.tags.addressables.taggedAddresses
|
||||||
|
@ -20,10 +20,10 @@
|
|||||||
*/
|
*/
|
||||||
package com.vitorpamplona.quartz.nip72ModCommunities.approval
|
package com.vitorpamplona.quartz.nip72ModCommunities.approval
|
||||||
|
|
||||||
import com.vitorpamplona.quartz.nip01Core.EventHintBundle
|
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.AddressableEvent
|
import com.vitorpamplona.quartz.nip01Core.core.AddressableEvent
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
|
||||||
import com.vitorpamplona.quartz.nip72ModCommunities.definition.CommunityDefinitionEvent
|
import com.vitorpamplona.quartz.nip72ModCommunities.definition.CommunityDefinitionEvent
|
||||||
|
|
||||||
fun TagArrayBuilder<CommunityPostApprovalEvent>.community(event: EventHintBundle<CommunityDefinitionEvent>) = add(event.toATag().toATagArray())
|
fun TagArrayBuilder<CommunityPostApprovalEvent>.community(event: EventHintBundle<CommunityDefinitionEvent>) = add(event.toATag().toATagArray())
|
||||||
|
@ -21,12 +21,12 @@
|
|||||||
package com.vitorpamplona.quartz.nip75ZapGoals
|
package com.vitorpamplona.quartz.nip75ZapGoals
|
||||||
|
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import com.vitorpamplona.quartz.nip01Core.EventHintBundle
|
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.AddressableEvent
|
import com.vitorpamplona.quartz.nip01Core.core.AddressableEvent
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.BaseAddressableEvent
|
import com.vitorpamplona.quartz.nip01Core.core.BaseAddressableEvent
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
|
||||||
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.hashtags.hashtags
|
import com.vitorpamplona.quartz.nip01Core.tags.hashtags.hashtags
|
||||||
import com.vitorpamplona.quartz.nip01Core.tags.references.reference
|
import com.vitorpamplona.quartz.nip01Core.tags.references.reference
|
||||||
|
@ -25,7 +25,7 @@ import java.security.SecureRandom
|
|||||||
object RandomInstance {
|
object RandomInstance {
|
||||||
private val randomizer = SecureRandom()
|
private val randomizer = SecureRandom()
|
||||||
|
|
||||||
fun int(bound: Int) = randomizer.nextInt(bound)
|
fun int(bound: Int = Int.MAX_VALUE) = randomizer.nextInt(bound)
|
||||||
|
|
||||||
fun bytes(size: Int) = ByteArray(size).also { randomizer.nextBytes(it) }
|
fun bytes(size: Int) = ByteArray(size).also { randomizer.nextBytes(it) }
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,114 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2024 Vitor Pamplona
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to use,
|
||||||
|
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||||
|
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||||
|
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.vitorpamplona.quartz.nip01Core.hints
|
||||||
|
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.core.hexToByteArray
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.hints.bloom.BloomFilterMurMur3
|
||||||
|
import com.vitorpamplona.quartz.utils.RandomInstance
|
||||||
|
import junit.framework.TestCase.assertEquals
|
||||||
|
import junit.framework.TestCase.assertFalse
|
||||||
|
import junit.framework.TestCase.assertTrue
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
class BloomFilterMurMur3Test {
|
||||||
|
val testEncoded = "100:10:AKiEIEQKALgRACEABA==:3"
|
||||||
|
val testInBinary = "00000000000101010010000100000100001000100101000000000000000111011000100000000000100001000000000000100000000000000000000000000000"
|
||||||
|
|
||||||
|
val key1 = "ca29c211f1c72d5b6622268ff43d2288ea2b2cb5b9aa196ff9f1704fc914b71b".hexToByteArray()
|
||||||
|
val key2 = "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c".hexToByteArray()
|
||||||
|
val key3 = "560c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c".hexToByteArray()
|
||||||
|
|
||||||
|
val keys =
|
||||||
|
mutableListOf<ByteArray>().apply {
|
||||||
|
for (seed in 0..1_000_000) {
|
||||||
|
add(RandomInstance.bytes(32))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testCreate() {
|
||||||
|
val bloomFilter = BloomFilterMurMur3(100, 10, commonSalt = 3)
|
||||||
|
bloomFilter.add(key1)
|
||||||
|
bloomFilter.add(key2)
|
||||||
|
|
||||||
|
assertEquals(testEncoded, bloomFilter.encode())
|
||||||
|
assertEquals(testInBinary, bloomFilter.printBits())
|
||||||
|
|
||||||
|
assertTrue(bloomFilter.mightContain(key1))
|
||||||
|
assertTrue(bloomFilter.mightContain(key2))
|
||||||
|
|
||||||
|
assertFalse(bloomFilter.mightContain(key3))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testDecoding() {
|
||||||
|
val bloomFilter = BloomFilterMurMur3.decode(testEncoded)
|
||||||
|
|
||||||
|
assertEquals(testEncoded, bloomFilter.encode())
|
||||||
|
assertEquals(testInBinary, bloomFilter.printBits())
|
||||||
|
|
||||||
|
assertTrue(bloomFilter.mightContain(key1))
|
||||||
|
assertTrue(bloomFilter.mightContain(key2))
|
||||||
|
|
||||||
|
assertFalse(bloomFilter.mightContain(key3))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun runProb() {
|
||||||
|
val bloomFilter = BloomFilterMurMur3.decode(testEncoded)
|
||||||
|
|
||||||
|
var failureCounter = 0
|
||||||
|
repeat(1_000_000) {
|
||||||
|
if (bloomFilter.mightContain(RandomInstance.bytes(32))) {
|
||||||
|
failureCounter++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertEquals(0, failureCounter)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun runProb2() {
|
||||||
|
val bloomFilter = BloomFilterMurMur3(10_000_000, 4)
|
||||||
|
keys.forEach(bloomFilter::add)
|
||||||
|
|
||||||
|
var failureCounter = 0
|
||||||
|
repeat(1_000_000) {
|
||||||
|
if (bloomFilter.mightContain(RandomInstance.bytes(32))) {
|
||||||
|
failureCounter++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertTrue("Failures $failureCounter ${failureCounter / 1_000_000.0}", failureCounter / 1_000_000.0f < 0.015)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun runProb3() {
|
||||||
|
val bloomFilter = BloomFilterMurMur3(10_000_000, 4)
|
||||||
|
keys.forEach(bloomFilter::add)
|
||||||
|
|
||||||
|
var failureCounter = 0
|
||||||
|
repeat(1_000_000) {
|
||||||
|
if (bloomFilter.mightContain(RandomInstance.bytes(32))) {
|
||||||
|
failureCounter++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertTrue("Failures $failureCounter ${failureCounter / 1_000_000.0}", failureCounter / 1_000_000.0f < 0.015)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,93 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2024 Vitor Pamplona
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to use,
|
||||||
|
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||||
|
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||||
|
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.vitorpamplona.quartz.nip01Core.hints
|
||||||
|
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.core.hexToByteArray
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.core.toHexKey
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.hints.types.PubKeyHint
|
||||||
|
import com.vitorpamplona.quartz.utils.RandomInstance
|
||||||
|
import junit.framework.TestCase.assertTrue
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
class HintIndexerTest {
|
||||||
|
val key1 = "ca29c211f1c72d5b6622268ff43d2288ea2b2cb5b9aa196ff9f1704fc914b71b".hexToByteArray()
|
||||||
|
val key2 = "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c".hexToByteArray()
|
||||||
|
val key3 = "560c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c".hexToByteArray()
|
||||||
|
|
||||||
|
val keys =
|
||||||
|
mutableListOf<HexKey>().apply {
|
||||||
|
for (seed in 0..1_000_000) {
|
||||||
|
add(RandomInstance.bytes(32).toHexKey())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val relays =
|
||||||
|
this.javaClass
|
||||||
|
.getResourceAsStream("relayDB.txt")
|
||||||
|
?.readAllBytes()
|
||||||
|
.toString()
|
||||||
|
.split("\n")
|
||||||
|
|
||||||
|
val keyHints =
|
||||||
|
keys
|
||||||
|
.map { key ->
|
||||||
|
(0..5).map { PubKeyHint(key, relays.random()) }
|
||||||
|
}.flatten()
|
||||||
|
|
||||||
|
val key1Relays = (0..5).map { relays.random() }
|
||||||
|
val key2Relays = (0..4).map { relays.random() }
|
||||||
|
val key3Relays = (0..3).map { relays.random() }
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun runExistingKeys() {
|
||||||
|
val indexer = HintIndexer()
|
||||||
|
keyHints.forEach {
|
||||||
|
indexer.index(it.id(), it.relay!!)
|
||||||
|
}
|
||||||
|
|
||||||
|
var failureCounter = 0
|
||||||
|
repeat(1000) {
|
||||||
|
val key = keys.random()
|
||||||
|
if (indexer.get(key.hexToByteArray()).isEmpty()) {
|
||||||
|
failureCounter++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assertTrue("Failures $failureCounter ${failureCounter / 1_000.0}", failureCounter / 1_000.0f < 0.015)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun runProb() {
|
||||||
|
val indexer = HintIndexer()
|
||||||
|
keyHints.forEach {
|
||||||
|
indexer.index(it.id(), it.relay!!)
|
||||||
|
}
|
||||||
|
|
||||||
|
var failureCounter = 0
|
||||||
|
repeat(1_000) {
|
||||||
|
if (indexer.get(RandomInstance.bytes(32)).isNotEmpty()) {
|
||||||
|
failureCounter++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertTrue("Failures $failureCounter ${failureCounter / 1_000.0}", failureCounter / 1_000.0f < 0.015)
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user