iterate entity metadata sequentially (#543)
* iterate entity metadata sequentially * r * c
This commit is contained in:
parent
195e3f9a5a
commit
7da654649d
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
'@status-im/js': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
iterate metadata sequentially
|
|
@ -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:
|
||||||
|
|
|
@ -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 (
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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 = (
|
||||||
|
|
Loading…
Reference in New Issue