iterate entity metadata sequentially (#543)

* iterate entity metadata sequentially

* r

* c
This commit is contained in:
Felicio Mununga 2024-03-26 14:28:54 +09:00 committed by GitHub
parent 195e3f9a5a
commit 7da654649d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 149 additions and 150 deletions

View File

@ -0,0 +1,5 @@
---
'@status-im/js': patch
---
iterate metadata sequentially

View File

@ -9,7 +9,10 @@ if (!publicKey) {
) )
} }
const environment = process.env.NEXT_PUBLIC_ENVIRONMENT as 'production' | 'test' const environment = process.env.NEXT_PUBLIC_ENVIRONMENT as
| 'development'
| 'preview'
| 'production'
/** /**
* For some reason the regular import fails with a server error: * For some reason the regular import fails with a server error:

View File

@ -8,7 +8,10 @@ if (!publicKey) {
) )
} }
const environment = process.env.ENVIRONMENT as 'production' | 'test' const environment = process.env.ENVIRONMENT as
| 'development'
| 'preview'
| 'production'
export const App = () => { export const App = () => {
return ( return (

View File

@ -132,7 +132,7 @@ class Client {
} }
static async start(options: ClientOptions): Promise<Client> { static async start(options: ClientOptions): Promise<Client> {
// const { environment = 'development' } = options const { environment = 'development' } = options
let waku: LightNode | undefined let waku: LightNode | undefined
let client: Client | undefined let client: Client | undefined
@ -161,7 +161,7 @@ class Client {
* >@see https://forum.vac.dev/t/waku-v2-scalability-studies/142/2 * >@see https://forum.vac.dev/t/waku-v2-scalability-studies/142/2
*/ */
bootstrap({ bootstrap({
list: peers['production'], list: peers[environment],
timeout: 0, timeout: 0,
// note: Infinity prevents connection // note: Infinity prevents connection
// tagTTL: Infinity, // tagTTL: Infinity,

View File

@ -14,6 +14,7 @@ const production = [
'/dns4/store-02.ac-cn-hongkong-c.shards.test.statusim.net/tcp/443/wss/p2p/16Uiu2HAm9CQhsuwPR54q27kNj9iaQVfyRzTGKrhFmr94oD8ujU6P', '/dns4/store-02.ac-cn-hongkong-c.shards.test.statusim.net/tcp/443/wss/p2p/16Uiu2HAm9CQhsuwPR54q27kNj9iaQVfyRzTGKrhFmr94oD8ujU6P',
] ]
// todo?: https://github.com/status-im/infra-shards/issues/29#issuecomment-1992729489 `shards.staging`; await integration in desktop and mobile
// note!: users may experience additional latency due to cross-regional connection // note!: users may experience additional latency due to cross-regional connection
// todo: use "dynamic" discovery protocol instead // todo: use "dynamic" discovery protocol instead
// todo?: use a regional map together with an environment variable for the peer selection (e.g. `VERCEL_REGION`, but probably limited to Serverless Functions) // todo?: use a regional map together with an environment variable for the peer selection (e.g. `VERCEL_REGION`, but probably limited to Serverless Functions)

View File

@ -37,7 +37,7 @@ import type { LightNode } from '@waku/interfaces'
export interface RequestClientOptions { export interface RequestClientOptions {
ethProviderApiKey: string ethProviderApiKey: string
// environment?: 'development' | 'preview' | 'production' environment?: 'development' | 'preview' | 'production'
} }
class RequestClient { class RequestClient {
@ -72,7 +72,7 @@ class RequestClient {
} }
static async start(options: RequestClientOptions): Promise<RequestClient> { static async start(options: RequestClientOptions): Promise<RequestClient> {
// const { environment = 'development' } = options const { environment = 'development' } = options
let waku: LightNode | undefined let waku: LightNode | undefined
let client: RequestClient | undefined let client: RequestClient | undefined
@ -89,7 +89,7 @@ class RequestClient {
libp2p: { libp2p: {
peerDiscovery: [ peerDiscovery: [
bootstrap({ bootstrap({
list: peers['production'], list: peers[environment],
timeout: 0, timeout: 0,
// note: Infinity prevents connection // note: Infinity prevents connection
// tagTTL: Infinity, // tagTTL: Infinity,
@ -205,104 +205,99 @@ class RequestClient {
const contentTopic = idToContentTopic(communityPublicKey) const contentTopic = idToContentTopic(communityPublicKey)
const symmetricKey = await generateKeyFromPassword(communityPublicKey) const symmetricKey = await generateKeyFromPassword(communityPublicKey)
let communityDescription: CommunityDescription | undefined = undefined const wakuMessageGenerator = this.waku.store.queryGenerator([
try { createDecoder(contentTopic, symmetricKey, {
// todo: use queryGenerator() instead clusterId: 16,
await this.waku.store.queryWithOrderedCallback( shard: 32,
[ }),
createDecoder(contentTopic, symmetricKey, { ])
clusterId: 16, for await (const wakuMessages of wakuMessageGenerator) {
shard: 32, for await (const wakuMessage of wakuMessages) {
}), if (!wakuMessage) {
], continue
async wakuMessage => { }
// handle
const message = this.handleWakuMessage(wakuMessage)
if (!message) { // handle
return const message = this.handleWakuMessage(wakuMessage)
} if (!message) {
continue
}
if ( if (
message.type !== message.type !== ApplicationMetadataMessage_Type.COMMUNITY_DESCRIPTION
ApplicationMetadataMessage_Type.COMMUNITY_DESCRIPTION ) {
) { continue
return }
}
// decode // decode
const decodedCommunityDescription = CommunityDescription.fromBinary( const decodedCommunityDescription = CommunityDescription.fromBinary(
message.payload message.payload
)
// validate
if (
!isClockValid(
BigInt(decodedCommunityDescription.clock),
message.timestamp
)
) {
continue
}
if (isEncrypted(decodedCommunityDescription.tokenPermissions)) {
// todo?: zod
const permission = Object.values(
decodedCommunityDescription.tokenPermissions
).find(
permission =>
permission.type ===
CommunityTokenPermission_Type.BECOME_TOKEN_OWNER
) )
// validate if (!permission) {
if ( continue
!isClockValid(
BigInt(decodedCommunityDescription.clock),
message.timestamp
)
) {
return
} }
// isSignatureValid const criteria = permission.tokenCriteria[0]
if (isEncrypted(decodedCommunityDescription.tokenPermissions)) { const contracts = criteria?.contractAddresses
// todo?: zod const chainId = Object.keys(contracts)[0]
const permission = Object.values(
decodedCommunityDescription.tokenPermissions
).find(
permission =>
permission.type ===
CommunityTokenPermission_Type.BECOME_TOKEN_OWNER
)
if (!permission) { if (!chainId) {
return continue
}
const criteria = permission.tokenCriteria[0]
const contracts = criteria?.contractAddresses
const chainId = Object.keys(contracts)[0]
if (!chainId) {
return
}
const ethereumClient = this.getEthereumClient(Number(chainId))
if (!ethereumClient) {
return
}
const ownerPublicKey = await ethereumClient.resolveOwner(
this.#contractAddresses[Number(chainId)]
.CommunityOwnerTokenRegistry,
communityPublicKey
)
if (ownerPublicKey !== message.signerPublicKey) {
return
}
} else if (
communityPublicKey !==
`0x${compressPublicKey(message.signerPublicKey)}`
) {
return
} }
if (!communityDescription) { const providerUrl = this.#ethProviderURLs[Number(chainId)]
communityDescription = decodedCommunityDescription
if (!providerUrl) {
continue
} }
// stop const ethereumClient = this.getEthereumClient(Number(chainId))
throw new Error('stop')
if (!ethereumClient) {
continue
}
const ownerPublicKey = await ethereumClient.resolveOwner(
this.#contractAddresses[Number(chainId)]
.CommunityOwnerTokenRegistry,
communityPublicKey
)
if (ownerPublicKey !== message.signerPublicKey) {
continue
}
} else if (
communityPublicKey !==
`0x${compressPublicKey(message.signerPublicKey)}`
) {
continue
} }
)
} catch {
// eslint-disable-next-line no-empty
}
return communityDescription // stop
return decodedCommunityDescription
}
}
} }
private fetchContactCodeAdvertisement = async ( private fetchContactCodeAdvertisement = async (
@ -313,67 +308,59 @@ class RequestClient {
`${publicKey}-contact-code` `${publicKey}-contact-code`
) )
let contactCodeAdvertisement: ContactCodeAdvertisement | undefined = const wakuMessageGenerator = this.waku.store.queryGenerator([
undefined createDecoder(contentTopic, symmetricKey, {
try { clusterId: 16,
await this.waku.store.queryWithOrderedCallback( shard: 32,
[ }),
createDecoder(contentTopic, symmetricKey, { ])
clusterId: 16, for await (const wakuMessages of wakuMessageGenerator) {
shard: 32, for await (const wakuMessage of wakuMessages) {
}), if (!wakuMessage) {
], continue
wakuMessage => {
// handle
const message = this.handleWakuMessage(wakuMessage)
if (!message) {
return
}
if (
message.type !==
ApplicationMetadataMessage_Type.CONTACT_CODE_ADVERTISEMENT
) {
return
}
// decode
const decodedContactCode = ContactCodeAdvertisement.fromBinary(
message.payload
)
// validate
if (!decodedContactCode.chatIdentity) {
return
}
if (
!isClockValid(
BigInt(decodedContactCode.chatIdentity.clock),
message.timestamp
)
) {
return
}
if (publicKey !== message.signerPublicKey) {
return
}
if (!contactCodeAdvertisement) {
contactCodeAdvertisement = decodedContactCode
}
// stop
throw new Error('stop')
} }
)
} catch {
// eslint-disable-next-line no-empty
}
return contactCodeAdvertisement // handle
const message = this.handleWakuMessage(wakuMessage)
if (!message) {
continue
}
if (
message.type !==
ApplicationMetadataMessage_Type.CONTACT_CODE_ADVERTISEMENT
) {
continue
}
// decode
const decodedContactCode = ContactCodeAdvertisement.fromBinary(
message.payload
)
// validate
if (!decodedContactCode.chatIdentity) {
continue
}
if (
!isClockValid(
BigInt(decodedContactCode.chatIdentity.clock),
message.timestamp
)
) {
continue
}
if (publicKey !== message.signerPublicKey) {
continue
}
// stop
return decodedContactCode
}
}
} }
private handleWakuMessage = ( private handleWakuMessage = (