Skip to content

Commit

Permalink
Merge branch 'develop' into chore-2487-pr-gate-actions
Browse files Browse the repository at this point in the history
  • Loading branch information
Isla Koenigsknecht authored May 7, 2024
2 parents 8f1b7cf + 5e1888d commit cd85d6a
Show file tree
Hide file tree
Showing 65 changed files with 500 additions and 499 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/e2e-android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ jobs:

steps:
- uses: actions/checkout@v4

with:
lfs: true

- uses: actions/setup-node@master
with:
node-version: 18.12.1
Expand Down
51 changes: 51 additions & 0 deletions .github/workflows/e2e-ios-self.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: Detox E2E iOS (self-hosted)

on:
# push:
# paths:
# - packages/mobile/**
# - packages/backend/**
# - packages/state-manager/**
# - .github/workflows/e2e-ios-self.yml

jobs:
detox-ios-self-hosted:
timeout-minutes: 25
runs-on: [self-hosted, macOS, ARM64, iOS]

steps:
- uses: actions/checkout@v4
with:
lfs: true

- name: Install dependencies
run: |
npm i
npm run lerna bootstrap --scope @quiet/eslint-config,@quiet/logger,@quiet/common,@quiet/types,@quiet/state-manager,@quiet/backend,@quiet/identity,@quiet/mobile,backend-bundle
- name: Install pods
run: |
cd packages/mobile/ios
pod install
- name: Install pm2
run: npm install pm2@latest -g

- name: Start metro
run: |
cd packages/mobile
pm2 --name METRO start npm -- start
- name: Build Detox
run: |
cd packages/mobile
detox build -c ios.sim.debug.ci
- name: Run basic tests
run: |
cd packages/mobile
detox test starter -c ios.sim.debug.ci
- name: Stop metro
if: always()
run: pm2 stop METRO
4 changes: 3 additions & 1 deletion .github/workflows/e2e-ios.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ jobs:

steps:
- uses: actions/checkout@v4

with:
lfs: true

- uses: actions/setup-node@master
with:
node-version: 18.12.1
Expand Down
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,16 @@

# Refactorings:

# Fixes
# Fixes:

* Disable spellCheck/autoCorrect on non-spelling sensitive fields like usernames and channels ([#373](https://github.com/TryQuiet/quiet/issues/373))
* Fixes issue with reconnecting to peers on resume on iOS ([#2424](https://github.com/TryQuiet/quiet/issues/2424))

# Chores

* Cleanup data directory at end of e2e tests
* Update github workflows for PR gating ([#2487](https://github.com/TryQuiet/quiet/issues/2487))
* Don't create duplicate CSRs when joining a community under certain circumstances ([#2321](https://github.com/TryQuiet/quiet/issues/2321))

[2.2.0]

Expand Down
4 changes: 2 additions & 2 deletions packages/backend/src/backendManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ export const runBackendMobile = async () => {

rn_bridge.channel.on('close', async () => {
const connectionsManager = app.get<ConnectionsManagerService>(ConnectionsManagerService)
connectionsManager.closeSocket()
await connectionsManager.pause()
})

rn_bridge.channel.on('open', async (msg: OpenServices) => {
Expand All @@ -123,7 +123,7 @@ export const runBackendMobile = async () => {
torControl.torControlParams.auth.value = msg.authCookie
proxyAgent.proxy.port = msg.httpTunnelPort

await connectionsManager.openSocket()
await connectionsManager.resume()
})
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,10 @@ describe('Connections manager', () => {
community,
network: { peerId: userIdentity.peerId, hiddenService: userIdentity.hiddenService },
})
libp2pService.connectedPeers.set(peerId.toString(), DateTime.utc().valueOf())
libp2pService.connectedPeers.set(peerId.toString(), {
connectedAtSeconds: DateTime.utc().valueOf(),
address: peerId.toString(),
})

// Peer disconnected
const remoteAddr = `${peerId.toString()}`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ import {
import Logger from '../common/logger'
import { CONFIG_OPTIONS, QUIET_DIR, SERVER_IO_PROVIDER, SOCKS_PROXY_AGENT } from '../const'
import { Libp2pService } from '../libp2p/libp2p.service'
import { Libp2pEvents, Libp2pNodeParams } from '../libp2p/libp2p.types'
import { Libp2pEvents, Libp2pNodeParams, Libp2pPeerInfo } from '../libp2p/libp2p.types'
import { LocalDbService } from '../local-db/local-db.service'
import { LocalDBKeys } from '../local-db/local-db.types'
import { RegistrationService } from '../registration/registration.service'
Expand All @@ -71,6 +71,7 @@ export class ConnectionsManagerService extends EventEmitter implements OnModuleI
public libp2pService: Libp2pService
private ports: GetPorts
isTorInit: TorInitState = TorInitState.NOT_STARTED
private peerInfo: Libp2pPeerInfo | undefined = undefined

private readonly logger = Logger(ConnectionsManagerService.name)
constructor(
Expand Down Expand Up @@ -209,7 +210,7 @@ export class ConnectionsManagerService extends EventEmitter implements OnModuleI
const network = await this.localDbService.getNetworkInfo()

if (community && network) {
const sortedPeers = await this.localDbService.getSortedPeers(community.peerList)
const sortedPeers = await this.localDbService.getSortedPeers(community.peerList ?? [])
this.logger('launchCommunityFromStorage - sorted peers', sortedPeers)
if (sortedPeers.length > 0) {
community.peerList = sortedPeers
Expand Down Expand Up @@ -246,6 +247,23 @@ export class ConnectionsManagerService extends EventEmitter implements OnModuleI
this.serverIoProvider.io.close()
}

public async pause() {
this.logger('Pausing!')
this.logger('Closing socket!')
this.closeSocket()
this.logger('Pausing libp2pService!')
this.peerInfo = await this.libp2pService?.pause()
this.logger('Found the following peer info on pause: ', this.peerInfo)
}

public async resume() {
this.logger('Resuming!')
this.logger('Reopening socket!')
await this.openSocket()
this.logger('Dialing peers with info: ', this.peerInfo)
await this.libp2pService?.redialPeers(this.peerInfo)
}

// This method is only used on iOS through rn-bridge for reacting on lifecycle changes
public async openSocket() {
await this.socketService.init()
Expand Down Expand Up @@ -558,6 +576,7 @@ export class ConnectionsManagerService extends EventEmitter implements OnModuleI
agent: this.socksProxyAgent,
localAddress: this.libp2pService.createLibp2pAddress(onionAddress, peerId.toString()),
targetPort: this.ports.libp2pHiddenService,
// Ignore local address
peers: peers ? peers.slice(1) : [],
psk: Libp2pService.generateLibp2pPSK(community.psk).fullKey,
}
Expand Down Expand Up @@ -625,6 +644,7 @@ export class ConnectionsManagerService extends EventEmitter implements OnModuleI
// Update Frontend with Initialized Communities
if (this.communityId) {
this.serverIoProvider.io.emit(SocketActionTypes.COMMUNITY_LAUNCHED, { id: this.communityId })
console.log('this.libp2pService.dialedPeers', this.libp2pService.dialedPeers)
console.log('this.libp2pService.connectedPeers', this.libp2pService.connectedPeers)
console.log('this.libp2pservice', this.libp2pService)
this.serverIoProvider.io.emit(
Expand Down
68 changes: 64 additions & 4 deletions packages/backend/src/nest/libp2p/libp2p.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { SERVER_IO_PROVIDER, SOCKS_PROXY_AGENT } from '../const'
import { ServerIoProviderTypes } from '../types'
import { webSockets } from '../websocketOverTor'
import { all } from '../websocketOverTor/filters'
import { Libp2pEvents, Libp2pNodeParams } from './libp2p.types'
import { Libp2pConnectedPeer, Libp2pEvents, Libp2pNodeParams, Libp2pPeerInfo } from './libp2p.types'
import { ProcessInChunksService } from './process-in-chunks.service'

const KEY_LENGTH = 32
Expand All @@ -29,7 +29,7 @@ export const LIBP2P_PSK_METADATA = '/key/swarm/psk/1.0.0/\n/base16/\n'
@Injectable()
export class Libp2pService extends EventEmitter {
public libp2pInstance: Libp2p | null
public connectedPeers: Map<string, number> = new Map()
public connectedPeers: Map<string, Libp2pConnectedPeer> = new Map()
public dialedPeers: Set<string> = new Set()
private readonly logger = Logger(Libp2pService.name)
constructor(
Expand All @@ -48,6 +48,21 @@ export class Libp2pService extends EventEmitter {
await this.libp2pInstance?.dial(multiaddr(peerAddress))
}

public getCurrentPeerInfo = (): Libp2pPeerInfo => {
return {
dialed: Array.from(this.dialedPeers),
connected: Array.from(this.connectedPeers.values()).map(peer => peer.address),
}
}

public pause = async (): Promise<Libp2pPeerInfo> => {
const peerInfo = this.getCurrentPeerInfo()
await this.hangUpPeers(peerInfo.dialed)
this.dialedPeers.clear()
this.connectedPeers.clear()
return peerInfo
}

public readonly createLibp2pAddress = (address: string, peerId: string): string => {
return createLibp2pAddress(address, peerId)
}
Expand All @@ -74,6 +89,47 @@ export class Libp2pService extends EventEmitter {
return { psk: psk.toString('base64'), fullKey }
}

public async hangUpPeers(peers: string[]) {
this.logger('Hanging up on all peers')
for (const peer of peers) {
await this.hangUpPeer(peer)
}
}

public async hangUpPeer(peerAddress: string) {
this.logger('Hanging up on peer', peerAddress)
await this.libp2pInstance?.hangUp(multiaddr(peerAddress))
this.dialedPeers.delete(peerAddress)
this.connectedPeers.delete(peerAddress)
}

/**
* Hang up existing peer connections and re-dial them. Specifically useful on
* iOS where Tor receives a new port when the app resumes from background and
* we want to close/re-open connections.
*/
public async redialPeers(peerInfo?: Libp2pPeerInfo) {
const dialed = peerInfo ? peerInfo.dialed : Array.from(this.dialedPeers)
const toDial = peerInfo
? [...peerInfo.connected, ...peerInfo.dialed]
: [...this.connectedPeers.keys(), ...this.dialedPeers]

if (dialed.length === 0) {
this.logger('No peers to redial!')
return
}

this.logger(`Re-dialing ${dialed.length} peers`)

// TODO: Sort peers
for (const peerAddress of dialed) {
await this.hangUpPeer(peerAddress)
}

this.processInChunksService.updateData(toDial)
await this.processInChunksService.process()
}

public async createInstance(params: Libp2pNodeParams): Promise<Libp2p> {
if (this.libp2pInstance) {
return this.libp2pInstance
Expand Down Expand Up @@ -157,7 +213,11 @@ export class Libp2pService extends EventEmitter {
const localPeerId = peerId.toString()
this.logger(`${localPeerId} connected to ${remotePeerId}`)

this.connectedPeers.set(remotePeerId, DateTime.utc().valueOf())
const connectedPeer: Libp2pConnectedPeer = {
address: peer.detail.remoteAddr.toString(),
connectedAtSeconds: DateTime.utc().valueOf(),
}
this.connectedPeers.set(remotePeerId, connectedPeer)
this.logger(`${localPeerId} is connected to ${this.connectedPeers.size} peers`)
this.logger(`${localPeerId} has ${this.libp2pInstance?.getConnections().length} open connections`)

Expand All @@ -176,7 +236,7 @@ export class Libp2pService extends EventEmitter {
}
this.logger(`${localPeerId} has ${this.libp2pInstance.getConnections().length} open connections`)

const connectionStartTime = this.connectedPeers.get(remotePeerId)
const connectionStartTime: number = this.connectedPeers.get(remotePeerId)!.connectedAtSeconds
if (!connectionStartTime) {
this.logger.error(`No connection start time for peer ${remotePeerId}`)
return
Expand Down
10 changes: 10 additions & 0 deletions packages/backend/src/nest/libp2p/libp2p.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,13 @@ export interface Libp2pNodeParams {
peers: string[]
psk: Uint8Array
}

export type Libp2pPeerInfo = {
dialed: string[]
connected: string[]
}

export type Libp2pConnectedPeer = {
address: string
connectedAtSeconds: number
}
18 changes: 3 additions & 15 deletions packages/backend/src/nest/local-db/local-db.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,21 +95,9 @@ export class LocalDbService {
}
}

public async getSortedPeers(
peers?: string[] | undefined,
includeLocalPeerAddress: boolean = true
): Promise<string[]> {
if (!peers) {
const currentCommunity = await this.getCurrentCommunity()
if (!currentCommunity) {
throw new Error('No peers were provided and no community was found to extract peers from')
}
peers = currentCommunity.peerList
if (!peers) {
throw new Error('No peers provided and no peers found on current stored community')
}
}

// I think we can move this into StorageService (keep this service
// focused on CRUD).
public async getSortedPeers(peers: string[], includeLocalPeerAddress: boolean = true): Promise<string[]> {
const peersStats = (await this.get(LocalDBKeys.PEERS)) || {}
const stats: NetworkStats[] = Object.values(peersStats)
const network = await this.getNetworkInfo()
Expand Down
10 changes: 7 additions & 3 deletions packages/backend/src/nest/registration/registration.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,14 @@ export class RegistrationService extends EventEmitter implements OnModuleInit {
}

public async tryIssueCertificates() {
this.logger('Trying to issue certificates', this.registrationEventInProgress, this.registrationEvents)
this.logger('Trying to process registration event')
// Process only a single registration event at a time so that we
// do not register two certificates with the same name.
if (!this.registrationEventInProgress) {
// Get the next event.
const event = this.registrationEvents.shift()
if (event) {
this.logger('Issuing certificates', event)
this.logger('Processing registration event', event)
// Event processing in progress
this.registrationEventInProgress = true

Expand All @@ -62,6 +62,7 @@ export class RegistrationService extends EventEmitter implements OnModuleInit {
certificates: (await this.storageService?.loadAllCertificates()) as string[],
})

this.logger('Finished processing registration event')
// Event processing finished
this.registrationEventInProgress = false

Expand All @@ -70,6 +71,8 @@ export class RegistrationService extends EventEmitter implements OnModuleInit {
setTimeout(this.tryIssueCertificates.bind(this), 0)
}
}
} else {
this.logger('Registration event processing already in progress')
}
}

Expand All @@ -90,12 +93,13 @@ export class RegistrationService extends EventEmitter implements OnModuleInit {
}

const pendingCsrs = await extractPendingCsrs(payload)
this.logger(`Issuing certificates`)
await Promise.all(
pendingCsrs.map(async csr => {
await this.registerUserCertificate(csr)
})
)
this.logger('Finished issuing certificates')
this.logger('Total certificates issued:', pendingCsrs.length)
}

// TODO: This doesn't save the owner's certificate in OrbitDB, so perhaps we
Expand Down
Loading

0 comments on commit cd85d6a

Please sign in to comment.