Skip to content
Merged
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
8 changes: 6 additions & 2 deletions ts/session/apis/seed_node_api/SeedNodeAPI.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import https from 'https';
import tls from 'tls';

import { setDefaultAutoSelectFamilyAttemptTimeout } from 'net';
import _ from 'lodash';

// eslint-disable-next-line import/no-named-default
import { default as insecureNodeFetch } from 'node-fetch';
import pRetry from 'p-retry';
Expand Down Expand Up @@ -275,7 +276,10 @@ async function getSnodesFromSeedUrl(urlObj: URL): Promise<Array<any>> {
agent: sslAgent,
};
window?.log?.info(`insecureNodeFetch => plaintext for getSnodesFromSeedUrl ${url}`);

// Note: node has a default timeout of 250ms to pick ipv4 or ipv6 address, but sometimes it times out
// Increase that duration to 500ms as it seems to be resolving our issues.
// see https://github.com/nodejs/undici/issues/2990#issuecomment-2408883876
setDefaultAutoSelectFamilyAttemptTimeout(500);
const response = await insecureNodeFetch(url, fetchOptions);

if (response.status !== 200) {
Expand Down
26 changes: 15 additions & 11 deletions ts/session/apis/snode_api/swarmPolling.ts
Original file line number Diff line number Diff line change
Expand Up @@ -977,7 +977,7 @@ export class SwarmPolling {
);
}

const allResultsFromUserProfile = await Promise.allSettled(
const firstResultWithMessagesUserProfile = await Promise.any(
swarmSnodes.map(async toPollFrom => {
// Note: always print something so we know if the polling is hanging
window.log.info(
Expand All @@ -996,21 +996,25 @@ export class SwarmPolling {
window.log.info(
`[onboarding] pollOnceForOurDisplayName of ${ed25519Str(pubkey.key)} from snode: ${ed25519Str(toPollFrom.pubkey_ed25519)} namespaces: ${[SnodeNamespaces.UserProfile]} returned: ${retrieved?.length}`
);
if (!retrieved?.length) {
/**
* Sometimes, a snode is out of sync with its swarm but still replies with what he thinks is the swarm's content.
* When that happens, we can get a "no display name" error, as indeed, that snode didn't have a config message on user profile.
* To fix this, we've added a check over all of the snodes of our swarm, and we pick the first one that reports having a config message on user profile.
* This won't take care of the case where a snode has a message with an empty display name, but it's not the root issue that this was added for.
*/

throw new Error(
`pollOnceForOurDisplayName of ${ed25519Str(pubkey.key)} from snode: ${ed25519Str(toPollFrom.pubkey_ed25519)} no results from user profile`
);
}
return retrieved;
})
);

const resultsFromUserProfile = flatten(
compact(
allResultsFromUserProfile
.filter(promise => promise.status === 'fulfilled')
.map(promise => promise.value)
)
);

// check if we just fetched the details from the config namespaces.
// If yes, merge them together and exclude them from the rest of the messages.
if (!resultsFromUserProfile?.length) {
if (!firstResultWithMessagesUserProfile?.length) {
throw new NotFoundError('[pollOnceForOurDisplayName] resultsFromUserProfile is empty');
}

Expand All @@ -1021,7 +1025,7 @@ export class SwarmPolling {
}

const userConfigMessagesWithNamespace: Array<Array<RetrieveMessageItemWithNamespace>> =
resultsFromUserProfile.map(r => {
firstResultWithMessagesUserProfile.map(r => {
return (r.messages.messages || []).map(m => {
return { ...m, namespace: SnodeNamespaces.UserProfile };
});
Expand Down