import path from 'path' ; import * as fs from 'fs' ; import { Participant } from '@statechannels/client-api-schema' ; import { makeDestination } from '@statechannels/wallet-core' ; import { Logger } from 'pino' ; import { utils } from 'ethers' ; import { Engine , extractDBConfigFromWalletConfig , EngineConfig , defaultTestWalletConfig , overwriteConfigWithDatabaseConnection , } from '../src/engine' ; import { DBAdmin , Wallet } from '../src' ; import { seedAlicesSigningWallet , seedBobsSigningWallet , } from '../src/db/seeds/1_signing_wallet_seeds' ; import { TestMessageService } from '../src/message-service/test-message-service' ; import { createLogger } from '../src/logger' ; import { LegacyTestMessageHandler } from '../src/message-service/legacy-test-message-service' ; interface TestPeerEngines { a : Engine ; b : Engine ; } export interface TestPeerWallets { a : Wallet ; b : Wallet ; } const aDatabase = 'server_wallet_test_a' ; const bDatabase = 'server_wallet_test_b' ; const ARTIFACTS_DIR = '../../artifacts' ; try { fs . mkdirSync ( ARTIFACTS_DIR ) ; } catch ( err ) { if ( err . message !== `EEXIST: file already exists, mkdir '${ ARTIFACTS_DIR }'` ) throw err ; } const baseConfig = defaultTestWalletConfig ( { loggingConfiguration : { logLevel : 'trace' , logDestination : path . join ( ARTIFACTS_DIR , 'with-peers.log' ) , } , syncConfiguration : { pollInterval : 500 , staleThreshold : 1000 , timeOutThreshold : 45000 } , } ) ; export const aWalletConfig = overwriteConfigWithDatabaseConnection ( baseConfig , { database : aDatabase , } ) ; export const bWalletConfig = overwriteConfigWithDatabaseConnection ( baseConfig , { database : bDatabase , } ) ; const { skipEvmValidation , metricsConfiguration : metrics } = baseConfig ; const baseEngineConfig = { skipEvmValidation , metrics , chainNetworkID : utils . hexlify ( baseConfig . networkConfiguration . chainNetworkID ) , workerThreadAmount : 0 , } ; export const aEngineConfig = { ... baseEngineConfig , dbConfig : extractDBConfigFromWalletConfig ( aWalletConfig ) , } ; export const bEngineConfig = { ... baseEngineConfig , dbConfig : extractDBConfigFromWalletConfig ( bWalletConfig ) , } ; const logger = createLogger ( baseConfig ) ; export type PeerSetup = { peerEngines : TestPeerEngines ; participantA : Participant ; participantB : Participant ; messageService : LegacyTestMessageHandler ; } ; export type PeerSetupWithWallets = PeerSetup & { peerWallets : TestPeerWallets ; } ; const isPeerSetupWithWallets = ( setup ) : setup is PeerSetupWithWallets => 'peerWallets' in setup ; export const participantIdA = 'a' ; export const participantIdB = 'b' ; const destinationA = makeDestination ( '0x00000000000000000000000000000000000000000000000000000000000aaaa1' ) ; const destinationB = makeDestination ( '0x00000000000000000000000000000000000000000000000000000000000bbbb2' ) ; export async function setupPeerWallets ( withWalletsSeeding = false ) { const peerSetup = await setupPeerEngines ( withWalletsSeeding ) ; const peerWallets = { a : await Wallet . create ( aWalletConfig , TestMessageService . create ) , b : await Wallet . create ( bWalletConfig , TestMessageService . create ) , } ; TestMessageService . linkMessageServices ( peerWallets . a . messageService , peerWallets . b . messageService ) ; return { ... peerSetup , peerWallets } ; } export async function setupPeerEngines ( withWalletSeeding = false ) { try { await Promise . all ( [ DBAdmin . createDatabase ( aWalletConfig ) , DBAdmin . createDatabase ( bWalletConfig ) , ] ) ; await Promise . all ( [ DBAdmin . migrateDatabase ( aWalletConfig ) , DBAdmin . migrateDatabase ( bWalletConfig ) , ] ) ; await Promise . all ( [ DBAdmin . truncateDatabase ( aWalletConfig ) , DBAdmin . truncateDatabase ( bWalletConfig ) , ] ) ; const peerEngines = { a : await Engine . create ( aEngineConfig , createLogger ( aWalletConfig ) ) , b : await Engine . create ( bEngineConfig , createLogger ( bWalletConfig ) ) , } ; if ( withWalletSeeding ) { await seedAlicesSigningWallet ( peerEngines . a . knex ) ; await seedBobsSigningWallet ( peerEngines . b . knex ) ; } const participantA = { signingAddress : await peerEngines . a . getSigningAddress ( ) , participantId : participantIdA , destination : destinationA , } ; const participantB = { signingAddress : await peerEngines . b . getSigningAddress ( ) , participantId : participantIdB , destination : destinationB , } ; const participantEngines = [ { participantId : participantIdA , engine : peerEngines . a } , { participantId : participantIdB , engine : peerEngines . b } , ] ; const messageService = new LegacyTestMessageHandler ( participantEngines ) ; logger . trace ( 'getPeersSetup complete' ) ; return { peerEngines , messageService , participantA , participantB , } ; } catch ( error ) { logger . error ( error , 'getPeersSetup failed' ) ; throw error ; } } export const teardownPeerSetup = async ( peerSetup ) : Promise < void > => { if ( ! peerSetup ) { logger . warn ( 'No PeerSetup so no teardown needed' ) ; return ; } try { const { messageService , peerEngines } = peerSetup ; await messageService . destroy ( ) ; if ( isPeerSetupWithWallets ( peerSetup ) ) { const { peerWallets } = peerSetup ; await Promise . all ( [ peerWallets . a . destroy ( ) , peerWallets . b . destroy ( ) ] ) ; } else { await Promise . all ( [ peerEngines . a . destroy ( ) , peerEngines . b . destroy ( ) ] ) ; } await Promise . all ( [ DBAdmin . truncateDatabase ( aWalletConfig ) , DBAdmin . truncateDatabase ( bWalletConfig ) , ] ) ; } catch ( error ) { logger . error ( error , 'peersTeardown failed' ) ; throw error ; } } ;