Skip to content

Commit

Permalink
moved update keylist into mediator
Browse files Browse the repository at this point in the history
Signed-off-by: Adam Burdett <[email protected]>
  • Loading branch information
burdettadam committed Jul 9, 2021
1 parent 6731aca commit 319690d
Show file tree
Hide file tree
Showing 9 changed files with 120 additions and 108 deletions.
4 changes: 3 additions & 1 deletion src/__tests__/agents.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ describe('agents', () => {
await bobAgent.closeAndDeleteWallet()
})

test('make a connection between agents and send a message over the connection', async () => {
test('make a connection between agents', async () => {
const aliceMessages = new Subject()
const bobMessages = new Subject()

Expand All @@ -42,7 +42,9 @@ describe('agents', () => {

expect(aliceConnection).toBeConnectedWith(bobConnection)
expect(bobConnection).toBeConnectedWith(aliceConnection)
})

test('send a message to connection', async () => {
const message = 'hello, world'
await aliceAgent.basicMessages.sendMessage(aliceConnection, message)

Expand Down
4 changes: 2 additions & 2 deletions src/agent/Agent.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { Logger } from '../logger'
import type { CredentialsModule } from '../modules/credentials/CredentialsModule'
import type { MessageRepository } from '../storage/MessageRepository'
import type { InboundTransporter } from '../transport/InboundTransporter'
import type { OutboundTransporter } from '../transport/OutboundTransporter'
Expand All @@ -15,7 +16,6 @@ import { container as baseContainer } from 'tsyringe'
import { InjectionSymbols } from '../constants'
import { BasicMessagesModule } from '../modules/basic-messages/BasicMessagesModule'
import { ConnectionsModule } from '../modules/connections/ConnectionsModule'
import { CredentialsModule } from '../modules/credentials/CredentialsModule'
import { LedgerModule } from '../modules/ledger/LedgerModule'
import { ProofsModule } from '../modules/proofs/ProofsModule'
import { MediatorModule } from '../modules/routing/MediatorModule'
Expand Down Expand Up @@ -87,12 +87,12 @@ export class Agent {
// Resolve instances after everything is registered
this.eventEmitter = this.container.resolve(EventEmitter)
this.messageSender = this.container.resolve(MessageSender)
this.container.registerInstance(InjectionSymbols.MessageSender, this.messageSender)
this.messageReceiver = this.container.resolve(MessageReceiver)
this.wallet = this.container.resolve(InjectionSymbols.Wallet)

// We set the modules in the constructor because that allows to set them as read-only
this.connections = this.container.resolve(ConnectionsModule)
this.credentials = this.container.resolve(CredentialsModule)
this.proofs = this.container.resolve(ProofsModule)
this.mediator = this.container.resolve(MediatorModule)
this.mediationRecipient = this.container.resolve(RecipientModule)
Expand Down
2 changes: 2 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ export const InjectionSymbols = {
InboundTransporter: Symbol('InboundTransporter'),
OutboundTransporter: Symbol('OutboundTransporter'),
TransportService: Symbol('TransportService'),
RecipientService: Symbol('RecipientService'),
ConnectionService: Symbol('ConnectionService'),
}

export const DID_COMM_TRANSPORT_QUEUE = 'didcomm:transport/queue'
73 changes: 6 additions & 67 deletions src/modules/connections/services/ConnectionService.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { AgentMessage } from '../../../agent/AgentMessage'
import type { InboundMessageContext } from '../../../agent/models/InboundMessageContext'
import type { KeylistUpdatedEvent, MediationRecord } from '../../../modules/routing'
import type { MediationRecord } from '../../../modules/routing'
import type { AckMessage } from '../../common'
import type { ConnectionStateChangedEvent } from '../ConnectionEvents'
import type { CustomConnectionTags } from '../repository/ConnectionRecord'
Expand All @@ -11,16 +11,12 @@ import { inject, scoped, Lifecycle } from 'tsyringe'

import { AgentConfig } from '../../../agent/AgentConfig'
import { EventEmitter } from '../../../agent/EventEmitter'
import { MessageSender } from '../../../agent/MessageSender'
import { createOutboundMessage } from '../../../agent/helpers'
import { InjectionSymbols } from '../../../constants'
import { signData, unpackAndVerifySignatureDecorator } from '../../../decorators/signature/SignatureDecoratorUtils'
import { AriesFrameworkError } from '../../../error'
import { RoutingEventTypes } from '../../../modules/routing/RoutingEvents'
import { waitForEvent } from '../../../modules/routing/services/RoutingService'
import { JsonTransformer } from '../../../utils/JsonTransformer'
import { Wallet } from '../../../wallet/Wallet'
import { KeylistUpdate, KeylistUpdateAction, KeylistUpdateMessage } from '../../routing/messages/KeylistUpdatedMessage'
import { RecipientService } from '../../routing/services/RecipientService'
import { ConnectionEventTypes } from '../ConnectionEvents'
import {
ConnectionInvitationMessage,
Expand Down Expand Up @@ -48,20 +44,20 @@ export class ConnectionService {
private config: AgentConfig
private connectionRepository: ConnectionRepository
private eventEmitter: EventEmitter
private messageSender: MessageSender
private mediationRecipientService: RecipientService

public constructor(
@inject(InjectionSymbols.Wallet) wallet: Wallet,
config: AgentConfig,
connectionRepository: ConnectionRepository,
eventEmitter: EventEmitter,
messageSender: MessageSender
@inject(InjectionSymbols.RecipientService) mediationRecipientService: RecipientService
) {
this.wallet = wallet
this.config = config
this.connectionRepository = connectionRepository
this.eventEmitter = eventEmitter
this.messageSender = messageSender
this.mediationRecipientService = mediationRecipientService
}

/**
Expand Down Expand Up @@ -433,63 +429,6 @@ export class ConnectionService {
return this.connectionRepository.getSingleByQuery({ threadId })
}

private async getRouting(mediationRecord: MediationRecord | undefined, routingKeys: string[], myEndpoint?: string) {
let endpoint
if (mediationRecord) {
routingKeys = [...routingKeys, ...mediationRecord.routingKeys]
endpoint = mediationRecord.endpoint
}
// Create and store new key
const [did, verkey] = await this.wallet.createDid()
if (mediationRecord) {
// new did has been created and mediator needs to be updated with the public key.
mediationRecord = await this.keylistUpdateAndAwait(mediationRecord, did)
} else {
// TODO: register recipient keys for relay
// TODO: check that recipient keys are in wallet
}
endpoint = endpoint ?? myEndpoint ?? this.config.getEndpoint()
const result = { mediationRecord, endpoint, routingKeys, did, verkey }
return result
}

public async keylistUpdateAndAwait(
mediationRecord: MediationRecord,
verKey: string,
timeout = 15000 // TODO: this should be a configurable value in agent config
): Promise<MediationRecord> {
const message = this.createKeylistUpdateMessage(verKey)
const connection = await this.getById(mediationRecord.connectionId)

const sendUpdateKeylist = async () => {
const outboundMessage = createOutboundMessage(connection, message)
await this.messageSender.sendMessage(outboundMessage)
}
const condition = async (event: KeylistUpdatedEvent) => {
return mediationRecord.id === event.payload.mediationRecord.id
}
const results = await waitForEvent(
sendUpdateKeylist,
RoutingEventTypes.RecipientKeylistUpdated,
condition,
timeout,
this.eventEmitter
)
return (results as KeylistUpdatedEvent).payload.mediationRecord
}

public createKeylistUpdateMessage(verkey: Verkey): KeylistUpdateMessage {
const keylistUpdateMessage = new KeylistUpdateMessage({
updates: [
new KeylistUpdate({
action: KeylistUpdateAction.add,
recipientKey: verkey,
}),
],
})
return keylistUpdateMessage
}

private async createConnection(options: {
role: ConnectionRole
state: ConnectionState
Expand All @@ -501,7 +440,7 @@ export class ConnectionService {
autoAcceptConnection?: boolean
tags?: CustomConnectionTags
}): Promise<ConnectionRecord> {
const myRouting = await this.getRouting(
const myRouting = await this.mediationRecipientService.getRouting(
//my routing
options.mediator,
options.routingKeys ?? [],
Expand Down
12 changes: 6 additions & 6 deletions src/modules/routing/RecipientModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ export class RecipientModule {
}

public async notifyKeylistUpdate(connection: ConnectionRecord, verkey: Verkey) {
const message = await this.connectionService.createKeylistUpdateMessage(verkey)
const message = await this.recipientService.createKeylistUpdateMessage(verkey)
const outboundMessage = createOutboundMessage(connection, message)
const response = await this.messageSender.sendMessage(outboundMessage)
return response
Expand All @@ -130,11 +130,11 @@ export class RecipientModule {
}

public async getMediatorConnections() {
const all_mediators = await this.getMediators()
const mediators_connection_ids = all_mediators ? all_mediators.map((mediator) => mediator.connectionId) : []
const all_connections = await this.connectionService.getAll()
return all_connections && mediators_connection_ids
? all_connections.filter((connection) => mediators_connection_ids.includes(connection.id))
const allMediators = await this.getMediators()
const mediatorConnectionIds = allMediators ? allMediators.map((mediator) => mediator.connectionId) : []
const allConnections = await this.connectionService.getAll()
return allConnections && mediatorConnectionIds
? allConnections.filter((connection) => mediatorConnectionIds.includes(connection.id))
: []
}

Expand Down
7 changes: 0 additions & 7 deletions src/modules/routing/repository/MediationRecord.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,4 @@ export class MediationRecord
}
}

public assertConnection(currentConnectionId: string) {
if (this.connectionId !== currentConnectionId) {
throw new AriesFrameworkError(
`Proof record is associated with connection '${this.connectionId}'. Current connection is '${currentConnectionId}'`
)
}
}
}
23 changes: 9 additions & 14 deletions src/modules/routing/services/MediatorService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import { MediationRole } from '../models/MediationRole'
import { MediationState } from '../models/MediationState'
import { MediationRepository } from '../repository/MediationRepository'

import { createRecord } from './RoutingService'
import { assertConnection, createRecord } from './RoutingService'

export interface RoutingTable {
[recipientKey: string]: ConnectionRecord | undefined
Expand Down Expand Up @@ -65,12 +65,6 @@ export class MediatorService {
this.connectionService = connectionService
}

private _assertConnection(connection: ConnectionRecord | undefined, msgType: BaseMessage): ConnectionRecord {
if (!connection) throw new AriesFrameworkError(`inbound connection is required for ${msgType.constructor.name}!`)
connection.assertReady()
return connection
}

public async processForwardMessage(messageContext: HandlerInboundMessage<ForwardHandler>) {
const { message, recipientVerkey } = messageContext

Expand All @@ -92,24 +86,24 @@ export class MediatorService {

public async processKeylistUpdateRequest(messageContext: InboundMessageContext<KeylistUpdateMessage>) {
const { message } = messageContext
const connection = this._assertConnection(messageContext.connection, KeylistUpdateMessage)
const connection = assertConnection(messageContext.connection)
const keylist: KeylistUpdated[] = []
const mediationRecord = await this.findRecipientByConnectionId(connection.id)
if (!mediationRecord) {
throw new Error(`mediation record for ${connection.id} not found!`)
}
for (const update of message.updates) {
const update_ = new KeylistUpdated({
const updated = new KeylistUpdated({
action: update.action,
recipientKey: update.recipientKey,
result: KeylistUpdateResult.NoChange,
})
if (update.action === KeylistUpdateAction.add) {
update_.result = await this.saveRoute(update.recipientKey, mediationRecord)
keylist.push(update_)
updated.result = await this.saveRoute(update.recipientKey, mediationRecord)
keylist.push(updated)
} else if (update.action === KeylistUpdateAction.remove) {
update_.result = await this.removeRoute(update.recipientKey, mediationRecord)
keylist.push(update_)
updated.result = await this.removeRoute(update.recipientKey, mediationRecord)
keylist.push(updated)
}
}
// emit event to send message that notifies recipient
Expand Down Expand Up @@ -160,6 +154,7 @@ export class MediatorService {
const records = await this.mediationRepository.findByQuery({ connectionId })
return records[0]
} catch (error) {
this.agentConfig.logger.warn(`Could not find record for connection: ${connectionId}`)
return null
}
}
Expand Down Expand Up @@ -189,7 +184,7 @@ export class MediatorService {

public async processMediationRequest(messageContext: InboundMessageContext<MediationRequestMessage>) {
// Assert connection
const connection = this._assertConnection(messageContext.connection, MediationRequestMessage)
const connection = assertConnection(messageContext.connection)

const mediationRecord = await createRecord(
{
Expand Down
Loading

0 comments on commit 319690d

Please sign in to comment.