Skip to content

Commit

Permalink
Merge pull request #578 from xmtp/np/renable-history-sync-frames-v3
Browse files Browse the repository at this point in the history
Re-Enable History Sync
  • Loading branch information
nplasterer authored Jan 2, 2025
2 parents dca77e3 + 0337171 commit 19c4460
Show file tree
Hide file tree
Showing 11 changed files with 151 additions and 120 deletions.
6 changes: 6 additions & 0 deletions .changeset/slimy-pugs-warn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@xmtp/react-native-sdk": patch
---

- Re-Enable History Sync
- Continued Performance improvements
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ repositories {
dependencies {
implementation project(':expo-modules-core')
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${getKotlinVersion()}"
implementation "org.xmtp:android:3.0.18"
implementation "org.xmtp:android:3.0.19"
implementation 'com.google.code.gson:gson:2.10.1'
implementation 'com.facebook.react:react-native:0.71.3'
implementation "com.daveanthonythomas.moshipack:moshipack:1.0.1"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ import org.xmtp.android.library.messages.PrivateKeyBuilder
import org.xmtp.android.library.messages.Signature
import org.xmtp.android.library.push.Service
import org.xmtp.android.library.push.XMTPPush
import uniffi.xmtpv3.XmtpApiClient
import uniffi.xmtpv3.org.xmtp.android.library.libxmtp.GroupPermissionPreconfiguration
import uniffi.xmtpv3.org.xmtp.android.library.libxmtp.PermissionOption
import java.io.BufferedReader
Expand Down Expand Up @@ -192,7 +191,6 @@ class XMTPModule : Module() {
}

private var clients: MutableMap<String, Client> = mutableMapOf()
private var apiClient: XmtpApiClient? = null
private var xmtpPush: XMTPPush? = null
private var signer: ReactNativeSigner? = null
private val isDebugEnabled = BuildConfig.DEBUG // TODO: consider making this configurable
Expand Down Expand Up @@ -251,13 +249,6 @@ class XMTPModule : Module() {
}
}

AsyncFunction("requestMessageHistorySync") Coroutine { installationId: String ->
withContext(Dispatchers.IO) {
val client = clients[installationId] ?: throw XMTPException("No client")
client.requestMessageHistorySync()
}
}

AsyncFunction("getInboxState") Coroutine { installationId: String, refreshFromNetwork: Boolean ->
withContext(Dispatchers.IO) {
val client = clients[installationId] ?: throw XMTPException("No client")
Expand Down Expand Up @@ -292,15 +283,6 @@ class XMTPModule : Module() {
signer?.handleSCW(id = requestID, signature = signature)
}

AsyncFunction("connectToApiBackend") Coroutine { environment: String ->
withContext(Dispatchers.IO) {
logV("connectToApiBackend")
val api = apiEnvironments(environment, null)
val xmtpApiClient = Client.connectToApiBackend(api)
apiClient = xmtpApiClient
}
}

AsyncFunction("createRandom") Coroutine { hasPreAuthenticateToInboxCallback: Boolean?, dbEncryptionKey: List<Int>, authParams: String ->
withContext(Dispatchers.IO) {
logV("createRandom")
Expand All @@ -311,11 +293,10 @@ class XMTPModule : Module() {
hasPreAuthenticateToInboxCallback,
)
val randomClient =
Client().create(account = privateKey, options = options, apiClient = apiClient)
Client().create(account = privateKey, options = options)

ContentJson.Companion
clients[randomClient.installationId] = randomClient
apiClient = randomClient.apiClient
ClientWrapper.encodeToObj(randomClient)
}
}
Expand All @@ -338,9 +319,8 @@ class XMTPModule : Module() {
hasAuthInboxCallback,
)
val client =
Client().create(account = reactSigner, options = options, apiClient = apiClient)
Client().create(account = reactSigner, options = options)
clients[client.installationId] = client
apiClient = client.apiClient
ContentJson.Companion
signer = null
sendEvent("authed", ClientWrapper.encodeToObj(client))
Expand All @@ -358,11 +338,9 @@ class XMTPModule : Module() {
address = address,
options = options,
inboxId = inboxId,
apiClient = apiClient
)
ContentJson.Companion
clients[client.installationId] = client
apiClient = client.apiClient
ClientWrapper.encodeToObj(client)
}
}
Expand Down Expand Up @@ -472,7 +450,6 @@ class XMTPModule : Module() {
peerAddresses,
context,
apiEnvironments(environment, null),
apiClient = apiClient
)
}
}
Expand All @@ -482,7 +459,7 @@ class XMTPModule : Module() {
try {
logV("getOrCreateInboxId")
Client.getOrCreateInboxId(
environment = apiEnvironments(environment, null),
api = apiEnvironments(environment, null),
address = address
)
} catch (e: Exception) {
Expand Down
16 changes: 8 additions & 8 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ PODS:
- hermes-engine/Pre-built (= 0.71.14)
- hermes-engine/Pre-built (0.71.14)
- libevent (2.1.12)
- LibXMTP (3.0.13)
- LibXMTP (3.0.15)
- MessagePacker (0.4.7)
- MMKV (2.0.0):
- MMKVCore (~> 2.0.0)
Expand Down Expand Up @@ -448,18 +448,18 @@ PODS:
- SQLCipher/standard (4.5.7):
- SQLCipher/common
- SwiftProtobuf (1.28.2)
- XMTP (3.0.19):
- XMTP (3.0.21):
- Connect-Swift (= 1.0.0)
- CryptoSwift (= 1.8.3)
- CSecp256k1 (~> 0.2)
- LibXMTP (= 3.0.13)
- LibXMTP (= 3.0.15)
- SQLCipher (= 4.5.7)
- XMTPReactNative (3.1.3):
- XMTPReactNative (3.1.4):
- CSecp256k1 (~> 0.2)
- ExpoModulesCore
- MessagePacker
- SQLCipher (= 4.5.7)
- XMTP (= 3.0.19)
- XMTP (= 3.0.21)
- Yoga (1.14.0)

DEPENDENCIES:
Expand Down Expand Up @@ -711,7 +711,7 @@ SPEC CHECKSUMS:
glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b
hermes-engine: d7cc127932c89c53374452d6f93473f1970d8e88
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
LibXMTP: 3b4b45c0edd404de164e26c7920af5ea0ebb3e17
LibXMTP: ad2c28778d7273c499b12dbf5493978c58d76858
MessagePacker: ab2fe250e86ea7aedd1a9ee47a37083edd41fd02
MMKV: f7d1d5945c8765f97f39c3d121f353d46735d801
MMKVCore: c04b296010fcb1d1638f2c69405096aac12f6390
Expand Down Expand Up @@ -762,8 +762,8 @@ SPEC CHECKSUMS:
RNSVG: d00c8f91c3cbf6d476451313a18f04d220d4f396
SQLCipher: 5e6bfb47323635c8b657b1b27d25c5f1baf63bf5
SwiftProtobuf: 4dbaffec76a39a8dc5da23b40af1a5dc01a4c02d
XMTP: b5311154b2a3cda7c07ce78ae9fa6d111bac979d
XMTPReactNative: 0d7f1d9b444eaeb3ffaf0fd29c6b71a0d6b6a29a
XMTP: 2c5dd2116778d1b547ac99b5b2396318d02c24d1
XMTPReactNative: 7745410f6367ed23198e546409d84987c6c5fea9
Yoga: e71803b4c1fff832ccf9b92541e00f9b873119b9

PODFILE CHECKSUM: 0e6fe50018f34e575d38dc6a1fdf1f99c9596cdd
Expand Down
10 changes: 5 additions & 5 deletions example/src/tests/conversationTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -415,14 +415,14 @@ test('can filter sync all by consent', async () => {
const boConvosFilteredUnknown =
await boClient.conversations.syncAllConversations('unknown')

assert(boConvos === 4, `Conversation length should be 4 but was ${boConvos}`)
assert(boConvos === 5, `Conversation length should be 5 but was ${boConvos}`)
assert(
boConvosFilteredAllowed === 2,
`Conversation length should be 2 but was ${boConvosFilteredAllowed}`
boConvosFilteredAllowed === 3,
`Conversation length should be 3 but was ${boConvosFilteredAllowed}`
)
assert(
boConvosFilteredUnknown === 2,
`Conversation length should be 2 but was ${boConvosFilteredUnknown}`
boConvosFilteredUnknown === 3,
`Conversation length should be 3 but was ${boConvosFilteredUnknown}`
)

return true
Expand Down
141 changes: 118 additions & 23 deletions example/src/tests/groupPerformanceTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
StaticAttachmentCodec,
} from 'xmtp-react-native-sdk'

import { Test, assert } from './test-utils'
import { Test, assert, createClients } from './test-utils'

export const groupPerformanceTests: Test[] = []
let counter = 1
Expand Down Expand Up @@ -88,26 +88,6 @@ test('building and creating', async () => {
const end3 = performance.now()
console.log(`Built a client with inboxId in ${end3 - start3}ms`)

await Client.connectToApiBackend('dev')
const start4 = performance.now()
await Client.createRandom({
env: 'dev',
appVersion: 'Testing/0.0.0',
dbEncryptionKey: keyBytes,
dbDirectory: dbDirPath,
codecs: [
new ReactionCodec(),
new ReplyCodec(),
new GroupUpdatedCodec(),
new StaticAttachmentCodec(),
new RemoteAttachmentCodec(),
],
})
const end4 = performance.now()
console.log(
`Created a client after connecting to backend in ${end4 - start4}ms`
)

assert(
end2 - start2 < end1 - start1,
'building a client should be faster than creating one'
Expand All @@ -120,10 +100,125 @@ test('building and creating', async () => {
end3 - start3 < end2 - start2,
'building a client with an inboxId should be faster than building without'
)

return true
})

test('creating a new conversation', async () => {
const [alixClient, boClient, caroClient] = await createClients(3, 'dev')

const start1 = performance.now()
await alixClient.conversations.newConversation(boClient.address)
const end1 = performance.now()
console.log(`Alix created a dm with Bo in ${end1 - start1}ms`)

await boClient.conversations.syncAllConversations()
const start2 = performance.now()
await boClient.conversations.newConversation(alixClient.address)
const end2 = performance.now()
console.log(`Bo found a dm with Alix in ${end2 - start2}ms`)

const start3 = performance.now()
await alixClient.conversations.newGroup([
boClient.address,
caroClient.address,
])
const end3 = performance.now()
console.log(`Alix created a group with Bo and Caro in ${end3 - start3}ms`)

const start4 = performance.now()
await alixClient.conversations.newGroup(
[boClient.address, caroClient.address],
{
permissionLevel: 'admin_only',
name: 'Group Name',
imageUrlSquare: 'imageurl.com',
description: 'group description',
pinnedFrameUrl: 'pinnedframe.com',
}
)
const end4 = performance.now()
console.log(
`Alix created a group with Bo and Caro with metadata in ${end4 - start4}ms`
)
assert(
end4 - start4 < end1 - start1,
'creating a client with an apiClient cached should be faster than creating one without'
end1 - start1 < 1000,
`Creating a new dm should be less than a second but was ${end1 - start1}`
)
assert(
end2 - start2 < 1000,
`Finding a existing dm should be less than a second but was ${end2 - start2}`
)
assert(
end3 - start3 < 1000,
`Creating a new group without metadata should be less than a second but was ${end3 - start3}`
)
assert(
end4 - start4 < 1000,
`Creating a new group with metadata should be less than a second but was ${end4 - start4}`
)
return true
})

test('sending messages in conversations', async () => {
const [alixClient, boClient, caroClient] = await createClients(10, 'local')
const alixDm = await alixClient.conversations.newConversation(
boClient.address
)
const alixGroup = await alixClient.conversations.newGroup([
boClient.address,
caroClient.address,
])
await boClient.conversations.syncAllConversations()
await caroClient.conversations.syncAllConversations()
const boDm = await alixClient.conversations.findConversation(alixDm.id)
const boGroup = await alixClient.conversations.findGroup(alixGroup.id)
const caroGroup = await alixClient.conversations.findConversation(
alixGroup.id
)

const start1 = performance.now()
await boDm?.send('message 1')
const end1 = performance.now()
console.log(`Bo sent message to dm in ${end1 - start1}ms`)

const start2 = performance.now()
await alixDm.send('message 2')
const end2 = performance.now()
console.log(`Alix sent message to dm in ${end2 - start2}ms`)

const start3 = performance.now()
await alixGroup.send('message 1')
const end3 = performance.now()
console.log(`Alix sent message to group in ${end3 - start3}ms`)

const start4 = performance.now()
await caroGroup?.send('message 2')
const end4 = performance.now()
console.log(`Caro sent message to group in ${end4 - start4}ms`)
const start5 = performance.now()
await boGroup?.send('message 3')
const end5 = performance.now()
console.log(`Bo sent message to group in ${end5 - start5}ms`)
assert(
end1 - start1 < 500,
`Sending message to dm should take less than .5s but was ${end1 - start1}`
)
assert(
end2 - start2 < 500,
`Sending message to dm should take less than .5s but was ${end2 - start2}`
)
assert(
end3 - start3 < 500,
`Sending message to group should take less than .5s but was ${end3 - start3}`
)
assert(
end4 - start4 < 500,
`Sending message to grop should take less than .5s but was ${end4 - start4}`
)
assert(
end5 - start5 < 500,
`Sending message to grop should take less than .5s but was ${end5 - start5}`
)
return true
})
8 changes: 6 additions & 2 deletions example/src/tests/test-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
GroupUpdatedCodec,
Group,
RemoteAttachmentCodec,
XMTPEnvironment,
} from 'xmtp-react-native-sdk'

export type Test = {
Expand All @@ -26,7 +27,10 @@ export function assert(condition: boolean, msg: string) {
}
}

export async function createClients(numClients: number): Promise<Client[]> {
export async function createClients(
numClients: number,
env?: XMTPEnvironment | undefined
): Promise<Client[]> {
const clients = []
for (let i = 0; i < numClients; i++) {
const keyBytes = new Uint8Array([
Expand All @@ -35,7 +39,7 @@ export async function createClients(numClients: number): Promise<Client[]> {
145,
])
const client = await Client.createRandom({
env: 'local',
env: env ?? 'local',
dbEncryptionKey: keyBytes,
})
client.register(new GroupUpdatedCodec())
Expand Down
Loading

0 comments on commit 19c4460

Please sign in to comment.