diff --git a/packages/backend/src/nest/local-db/local-db.service.ts b/packages/backend/src/nest/local-db/local-db.service.ts index 3c309ca20f..fcbecc41c3 100644 --- a/packages/backend/src/nest/local-db/local-db.service.ts +++ b/packages/backend/src/nest/local-db/local-db.service.ts @@ -1,7 +1,7 @@ import { Inject, Injectable } from '@nestjs/common' import { Level } from 'level' import { NetworkStats } from '@quiet/types' -import { sortPeers } from '@quiet/common' +import { filterAndSortPeers } from '@quiet/common' import { LEVEL_DB } from '../const' import { LocalDBKeys, LocalDbStatus } from './local-db.types' import Logger from '../common/logger' @@ -75,6 +75,6 @@ export class LocalDbService { console.log('getSortedPeers peers got', peers) const peersStats = (await this.get(LocalDBKeys.PEERS)) || {} const stats: NetworkStats[] = Object.values(peersStats) - return sortPeers(peers, stats) + return filterAndSortPeers(peers, stats) } } diff --git a/packages/common/src/libp2p.test.ts b/packages/common/src/libp2p.test.ts new file mode 100644 index 0000000000..5a623aadb7 --- /dev/null +++ b/packages/common/src/libp2p.test.ts @@ -0,0 +1,20 @@ +import { filterAndSortPeers } from './sortPeers' + +describe('filterValidAddresses', () => { + it('filters out invalid addresses', () => { + const valid = [ + '/dns4/gloao6h5plwjy4tdlze24zzgcxll6upq2ex2fmu2ohhyu4gtys4nrjad.onion/tcp/443/ws/p2p/QmZoiJNAvCffeEHBjk766nLuKVdkxkAT7wfFJDPPLsbKSE', + '/dns4/gloao6h5plwjy4tdlze24zzgcxll6upq2ex2fmu2ohhyu4gtys4nrjad.onion/tcp/80/ws/p2p/QmZoiJNAvCffeEHBjk766nLuKVdkxkAT7wfFJDPPLsbKSE', + ] + const addresses = [ + '/dns4/gloao6h5plwjy4tdlze24zzgcxll6upq2ex2fmu2ohhyu4gtys4nrjad.onion/tcp/443/wss/p2p/QmZoiJNAvCffeEHBjk766nLuKVdkxkAT7wfFJDPPLsbKSE', + ...valid, + 'invalidAddress', + '/dns4/somethingElse.onion/tcp/443/wss/p2p/QmZoiJNAvCffeEHBjk766nLuKVdkxkAT7wfFJDPPLsbKSA', + '/dns4/gloao6h5plwjy4tdlze24zzgcxll6upq2ex2fmu2ohhyu4gtys4nrjad.onion/tcp/443/ws/p2p/QmZoiJNAvCffeEHBjk766nLuKVdkxkAT7wfFJDPPLsbK', + '/dns4/gloao6h5plwjy4tdlze24zzgcxll6upq2ex2fmu2ohhyu4gtys4nrj.onion/tcp/443/ws/p2p/QmZoiJNAvCffeEHBjk766nLuKVdkxkAT7wfFJDPPLsbKSE', + 'QmZoiJNAvCffeEHBjk766nLuKVdkxkAT7wfFJDPPLsbK', + ] + expect(filterAndSortPeers(addresses, [])).toEqual(valid) + }) +}) diff --git a/packages/common/src/libp2p.ts b/packages/common/src/libp2p.ts index b2fb70e83f..4ada2cb6b9 100644 --- a/packages/common/src/libp2p.ts +++ b/packages/common/src/libp2p.ts @@ -17,3 +17,7 @@ export const isPSKcodeValid = (psk: string): boolean => { const _psk = psk.trim() return validator.isBase64(_psk) && _psk.length === PSK_LENGTH } + +export const filterValidAddresses = (addresses: string[]) => { + return addresses.filter(add => add.match(/^\/dns4\/[a-z0-9]{56}.onion\/tcp\/(443|80)\/ws\/p2p\/[a-zA-Z0-9]{46}$/g)) +} diff --git a/packages/common/src/sortPeers.ts b/packages/common/src/sortPeers.ts index 0ac9efcf6a..2b92cd1ea8 100644 --- a/packages/common/src/sortPeers.ts +++ b/packages/common/src/sortPeers.ts @@ -1,17 +1,17 @@ import { type NetworkStats } from '@quiet/types' import { isDefined } from './helpers' +import { filterValidAddresses } from './libp2p' /** This is the very simple algorithm for evaluating the most wanted peers. +0. Filters out invalid peers addresses 1. It takes the peers stats list that contains statistics for every peer our node was ever connected to. 2. Two sorted arrays are created - one sorted by last seen and other by most uptime shared. 3. Arrays are merged taking one element from list one and one element from the second list. Duplicates are ommited 4. We end up with mix of last seen and most uptime descending array of peers, the it is enchanced to libp2p address. */ -export const sortPeers = (peersAddresses: string[], stats: NetworkStats[]): string[] => { - peersAddresses = peersAddresses.filter(add => - add.match(/^\/dns4\/[a-z0-9]{56}.onion\/tcp\/(443|80)\/ws\/p2p\/[a-zA-Z0-9]{46}$/g) - ) +export const filterAndSortPeers = (peersAddresses: string[], stats: NetworkStats[]): string[] => { + peersAddresses = filterValidAddresses(peersAddresses) const lastSeenSorted = [...stats].sort((a, b) => { return b.lastSeen - a.lastSeen }) diff --git a/packages/state-manager/src/sagas/appConnection/connection.selectors.ts b/packages/state-manager/src/sagas/appConnection/connection.selectors.ts index b0f7606fcf..2d2bff0cdb 100644 --- a/packages/state-manager/src/sagas/appConnection/connection.selectors.ts +++ b/packages/state-manager/src/sagas/appConnection/connection.selectors.ts @@ -7,7 +7,7 @@ import { peersStatsAdapter } from './connection.adapter' import { connectedPeers } from '../network/network.selectors' import { type NetworkStats } from './connection.types' import { type User } from '../users/users.types' -import { sortPeers } from '@quiet/common' +import { filterAndSortPeers } from '@quiet/common' const connectionSlice: CreatedSelectors[StoreKeys.Connection] = (state: StoreState) => state[StoreKeys.Connection] @@ -33,7 +33,7 @@ export const peerList = createSelector( stats = peersStatsAdapter.getSelectors().selectAll(reducerState.peersStats) } - return sortPeers(arr, stats) + return filterAndSortPeers(arr, stats) } )