Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Potential fork reproduction #335

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.xmtp.android.library

import android.util.Log
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import kotlinx.coroutines.CoroutineScope
Expand All @@ -13,6 +14,7 @@ import org.junit.runner.RunWith
import org.xmtp.android.library.messages.PrivateKey
import org.xmtp.android.library.messages.PrivateKeyBuilder
import org.xmtp.android.library.messages.walletAddress
import java.lang.Thread.sleep
import java.security.SecureRandom

@RunWith(AndroidJUnit4::class)
Expand All @@ -26,6 +28,9 @@ class ConversationsTest {
private lateinit var caroWallet: PrivateKeyBuilder
private lateinit var caro: PrivateKey
private lateinit var caroClient: Client
private lateinit var davonWallet: PrivateKeyBuilder
private lateinit var davon: PrivateKey
private lateinit var davonClient: Client
private lateinit var fixtures: Fixtures

@Before
Expand All @@ -37,10 +42,13 @@ class ConversationsTest {
bo = fixtures.bo
caroWallet = fixtures.caroAccount
caro = fixtures.caro
davonWallet = fixtures.davonAccount
davon = fixtures.davon

alixClient = fixtures.alixClient
boClient = fixtures.boClient
caroClient = fixtures.caroClient
davonClient = fixtures.davonClient
}

@Test
Expand Down Expand Up @@ -234,4 +242,219 @@ class ConversationsTest {
assertEquals(dm2.consentState(), ConsentState.ALLOWED)
}
}

@Test
fun testInstallationsDoNotForkMinimum() {
val key = SecureRandom().generateSeed(32)
val context = InstrumentationRegistry.getInstrumentation().targetContext

val alixGroup =
runBlocking {
alixClient.conversations.newGroup(
listOf(
bo.walletAddress,
caro.walletAddress
)
)
}
runBlocking {
boClient.conversations.sync()
caroClient.conversations.sync()
}
val boGroup = boClient.findGroup(alixGroup.id)!!
val caroGroup = boClient.findGroup(alixGroup.id)!!

runBlocking {
alixGroup.send("Message 1")
boGroup.send("Message 2")
caroGroup.send("Message 3")
alixGroup.send("Message 4")
alixGroup.send("Message 5")
}

runBlocking {
alixGroup.sync()
boGroup.sync()
caroGroup.sync()
}

assertEquals(alixGroup.messages().size, 6)
assertEquals(boGroup.messages().size, 5)
assertEquals(caroGroup.messages().size, 5)

val clientOptions2 = ClientOptions(
ClientOptions.Api(XMTPEnvironment.LOCAL, false),
appContext = context,
dbEncryptionKey = key,
dbDirectory = context.filesDir.absolutePath.toString()
)

val alixClient2 =
runBlocking { Client().create(account = alixWallet, options = clientOptions2) }
runBlocking {
alixClient.conversations.sync()
boClient.conversations.sync()
caroClient.conversations.sync()
alixClient.conversations.syncAllConversations()
boClient.conversations.syncAllConversations()
caroClient.conversations.syncAllConversations()
alixClient2.conversations.sync()
}
val alixGroup2 = alixClient2.findGroup(alixGroup.id)!!

runBlocking {
alixGroup2.send("Message 6")
boGroup.send("Message 7")
caroGroup.send("Message 8")
alixGroup.send("Message 9")
alixGroup2.send("Message 10")
}

runBlocking {
alixClient.conversations.syncAllConversations()
boClient.conversations.syncAllConversations()
caroClient.conversations.syncAllConversations()
alixClient2.conversations.syncAllConversations()
}

assertEquals(alixGroup.messages().size, 11)
assertEquals(boGroup.messages().size, 10)
assertEquals(caroGroup.messages().size, 10)
assertEquals(alixGroup2.messages().size, 5) // expect 5 but was 3 -- On a fork with just Alix2 & Caro
}

@Test
fun testInstallationsDoNotFork() {
runBlocking {
val key = SecureRandom().generateSeed(32)
val context = InstrumentationRegistry.getInstrumentation().targetContext

val alixGroup =
alixClient.conversations.newGroup(
listOf(
bo.walletAddress,
caro.walletAddress
)
)
boClient.conversations.sync()
caroClient.conversations.sync()
val boGroup = boClient.findGroup(alixGroup.id)!!
val caroGroup = boClient.findGroup(alixGroup.id)!!

alixGroup.send("Message 1")
boGroup.send("Message 2")
caroGroup.send("Message 3")
alixGroup.send("Message 4")
alixGroup.send("Message 5")
caroGroup.send("Message 6")

assertEquals(alixGroup.messages().size, 6)
assertEquals(boGroup.messages().size, 6)
assertEquals(caroGroup.messages().size, 6)

val clientOptions2 = ClientOptions(
ClientOptions.Api(XMTPEnvironment.LOCAL, false),
appContext = context,
dbEncryptionKey = key,
dbDirectory = context.filesDir.absolutePath.toString()
)

val alixClient2 = Client().create(account = alixWallet, options = clientOptions2)
alixClient.conversations.sync()
boClient.conversations.sync()
caroClient.conversations.sync()
alixClient.conversations.syncAllConversations()
boClient.conversations.syncAllConversations()
caroClient.conversations.syncAllConversations()
alixClient2.conversations.sync()
val alixGroup2 = alixClient2.findGroup(alixGroup.id)!!

alixGroup2.send("Message 7")
boGroup.send("Message 8")
caroGroup.send("Message 9")
alixGroup.send("Message 10")
alixGroup2.send("Message 11")
alixGroup.send("Message 12")
alixGroup2.send("Message 13")
alixGroup.send("Message 14")
caroGroup.send("Message 15")

alixClient.conversations.syncAllConversations()
boClient.conversations.syncAllConversations()
caroClient.conversations.syncAllConversations()
alixClient2.conversations.syncAllConversations()

assertEquals(alixGroup.messages().size, 16)
assertEquals(boGroup.messages().size, 15)
assertEquals(caroGroup.messages().size, 15)
assertEquals(alixGroup2.messages().size, 9) // expect 9 but was 7

// +1 more message
alixGroup2.addMembers(listOf(davon.walletAddress))
davonClient.conversations.sync()
val davonGroup = davonClient.findGroup(alixGroup.id)!!

alixGroup2.send("Message 16")
alixGroup.send("Message 17")
alixGroup2.send("Message 18")
alixGroup.send("Message 19")
davonGroup.send("Message 20")

alixClient.conversations.syncAllConversations()
boClient.conversations.syncAllConversations()
caroClient.conversations.syncAllConversations()
alixClient2.conversations.syncAllConversations()
davonClient.conversations.syncAllConversations()

assertEquals(alixGroup.messages().size, 22)
assertEquals(boGroup.messages().size, 21)
assertEquals(caroGroup.messages().size, 21)
alixGroup2.messages().forEach {
Log.d("LOPI", it.body)
}
assertEquals(alixGroup2.messages().size, 15) // Expected 15 but was 13
assertEquals(davonGroup.messages().size, 5) // Expected 5 but was 4

val boClient2 = Client().create(account = boWallet, options = clientOptions2)

alixGroup2.send("Message 21")
alixGroup.send("Message 22")
alixGroup2.send("Message 23")
alixGroup.send("Message 24")
boGroup.send("Message 25")

alixClient.conversations.sync()
boClient.conversations.sync()
caroClient.conversations.sync()
alixClient2.conversations.sync()
alixClient.conversations.syncAllConversations()
boClient.conversations.syncAllConversations()
caroClient.conversations.syncAllConversations()
davonClient.conversations.syncAllConversations()
alixClient2.conversations.syncAllConversations()
boClient2.conversations.sync()
boClient2.conversations.syncAllConversations()
// val boGroup2 = boClient2.findGroup(alixGroup.id)!! // Cant find the group?

alixGroup2.send("Message 26")
alixGroup.send("Message 27")
alixGroup2.send("Message 28")
alixGroup.send("Message 29")
davonGroup.send("Message 30")

alixClient.conversations.syncAllConversations()
boClient.conversations.syncAllConversations()
caroClient.conversations.syncAllConversations()
davonClient.conversations.syncAllConversations()
alixClient2.conversations.syncAllConversations()
boClient2.conversations.syncAllConversations()

assertEquals(alixGroup.messages().size, 32)
assertEquals(boGroup.messages().size, 31)
assertEquals(caroGroup.messages().size, 31)
// assertEquals(alixGroup2.messages().size, 25) // Expected 25 was 23
// assertEquals(davonGroup.messages().size, 15) // Expected 15 was 14
// assertEquals(boGroup2.messages().size, 5)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ class Fixtures {
val alixAccount = PrivateKeyBuilder()
val boAccount = PrivateKeyBuilder()
val caroAccount = PrivateKeyBuilder()
val davonAccount = PrivateKeyBuilder()

var alix: PrivateKey = alixAccount.getPrivateKey()
var alixClient: Client =
Expand All @@ -165,6 +166,10 @@ class Fixtures {
var caro: PrivateKey = caroAccount.getPrivateKey()
var caroClient: Client =
runBlocking { Client().create(account = caroAccount, options = clientOptions) }

var davon: PrivateKey = davonAccount.getPrivateKey()
var davonClient: Client =
runBlocking { Client().create(account = davonAccount, options = clientOptions) }
}

fun fixtures(): Fixtures =
Expand Down
2 changes: 1 addition & 1 deletion library/src/main/java/org/xmtp/android/library/Client.kt
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ class Client() {
inboxId = inboxId,
nonce = 0.toULong(),
legacySignedPrivateKeyProto = null,
historySyncUrl = options.historySyncUrl
historySyncUrl = null
)

options.preAuthenticateToInboxCallback?.let {
Expand Down
Loading