diff --git a/.env b/.env index 9157b9b..6b6012f 100644 --- a/.env +++ b/.env @@ -3,4 +3,3 @@ ETHCONNECT_URL=http://127.0.0.1:5102 ETHCONNECT_INSTANCE=/contracts/erc1155 ETHCONNECT_TOPIC=token CONTRACT_ADDRESS= -AUTO_INIT=true diff --git a/src/app.module.ts b/src/app.module.ts index de35ace..a0fe6ec 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -1,4 +1,4 @@ -// Copyright © 2021 Kaleido, Inc. +// Copyright © 2024 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // diff --git a/src/event-stream/event-stream.interfaces.ts b/src/event-stream/event-stream.interfaces.ts index 9fb2cb6..34a40e1 100644 --- a/src/event-stream/event-stream.interfaces.ts +++ b/src/event-stream/event-stream.interfaces.ts @@ -1,4 +1,4 @@ -// Copyright © 2022 Kaleido, Inc. +// Copyright © 2024 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // diff --git a/src/event-stream/event-stream.module.ts b/src/event-stream/event-stream.module.ts index 9087296..e677c8d 100644 --- a/src/event-stream/event-stream.module.ts +++ b/src/event-stream/event-stream.module.ts @@ -1,4 +1,4 @@ -// Copyright © 2022 Kaleido, Inc. +// Copyright © 2024 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // diff --git a/src/event-stream/event-stream.service.spec.ts b/src/event-stream/event-stream.service.spec.ts index 5266f16..ffe98dc 100644 --- a/src/event-stream/event-stream.service.spec.ts +++ b/src/event-stream/event-stream.service.spec.ts @@ -1,4 +1,4 @@ -// Copyright © 2022 Kaleido, Inc. +// Copyright © 2024 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // diff --git a/src/event-stream/event-stream.service.ts b/src/event-stream/event-stream.service.ts index 0bc16a5..5ad0196 100644 --- a/src/event-stream/event-stream.service.ts +++ b/src/event-stream/event-stream.service.ts @@ -1,4 +1,4 @@ -// Copyright © 2022 Kaleido, Inc. +// Copyright © 2024 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // @@ -22,7 +22,7 @@ import WebSocket from 'ws'; import { FFRequestIDHeader } from '../request-context/constants'; import { Context, newContext } from '../request-context/request-context.decorator'; import { IAbiMethod } from '../tokens/tokens.interfaces'; -import { getHttpRequestOptions, getWebsocketOptions } from '../utils'; +import { eventStreamName, getHttpRequestOptions, getWebsocketOptions } from '../utils'; import { Event, EventBatch, @@ -68,7 +68,7 @@ export class EventStreamSocket { } else { this.logger.log('Event stream websocket connected'); } - this.produce({ type: 'listen', topic: `${this.topic}/${this.namespace}` }); + this.produce({ type: 'listen', topic: `${eventStreamName(this.topic, this.namespace)}` }); this.produce({ type: 'listenreplies' }); this.ping(); }) @@ -84,7 +84,7 @@ export class EventStreamSocket { } }) .on('message', (message: string) => { - this.logger.debug(`WS => ${message}`); + this.logger.verbose(`WS => ${message}`); this.handleMessage(JSON.parse(message)); }) .on('pong', () => { @@ -111,11 +111,19 @@ export class EventStreamSocket { } ack(batchNumber: number | undefined) { - this.produce({ type: 'ack', topic: `${this.topic}/${this.namespace}`, batchNumber }); + this.produce({ + type: 'ack', + topic: `${eventStreamName(this.topic, this.namespace)}`, + batchNumber, + }); } nack(batchNumber: number | undefined) { - this.produce({ type: 'nack', topic: `${this.topic}/${this.namespace}`, batchNumber }); + this.produce({ + type: 'nack', + topic: `${eventStreamName(this.topic, this.namespace)}`, + batchNumber, + }); } close() { @@ -345,7 +353,7 @@ export class EventStreamService { handleEvents: (events: EventBatch) => void, handleReceipt: (receipt: EventStreamReply) => void, ) { - const name = `${topic}/${namespace}`; + const name = eventStreamName(topic, namespace); await this.createOrUpdateStream(newContext(), name, topic); return new EventStreamSocket( diff --git a/src/eventstream-proxy/eventstream-proxy.base.ts b/src/eventstream-proxy/eventstream-proxy.base.ts index af6ba09..fdb2a55 100644 --- a/src/eventstream-proxy/eventstream-proxy.base.ts +++ b/src/eventstream-proxy/eventstream-proxy.base.ts @@ -1,4 +1,4 @@ -// Copyright © 2022 Kaleido, Inc. +// Copyright © 2024 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // @@ -15,12 +15,12 @@ // limitations under the License. import { Logger } from '@nestjs/common'; -import { MessageBody, SubscribeMessage } from '@nestjs/websockets'; import { v4 as uuidv4 } from 'uuid'; import { Context, newContext } from '../request-context/request-context.decorator'; import { EventBatch, EventStreamReply } from '../event-stream/event-stream.interfaces'; import { EventStreamService, EventStreamSocket } from '../event-stream/event-stream.service'; import { + WebSocketAck, WebSocketActionBase, WebSocketEventsBase, WebSocketEx, @@ -49,7 +49,8 @@ export abstract class EventStreamProxyBase extends WebSocketEventsBase { private connectListeners: ConnectionListener[] = []; private eventListeners: EventListener[] = []; - private awaitingAck: WebSocketMessageWithId[] = []; + // Map of client IDs to all the messages for which we are awaiting an ack + private awaitingAck: Map = new Map(); private subscriptionNames = new Map(); private queue = Promise.resolve(); @@ -75,6 +76,9 @@ export abstract class EventStreamProxyBase extends WebSocketEventsBase { const startAction = action as WebSocketStart; this.startListening(client, startAction.namespace); break; + case 'ack': + const ackAction = action as WebSocketAck; + this.handleAck(client, ackAction); } }); } @@ -134,12 +138,13 @@ export abstract class EventStreamProxyBase extends WebSocketEventsBase { // Nack any messages that are inflight for that namespace const nackedMessageIds: Set = new Set(); this.awaitingAck - .filter(msg => msg.namespace === namespace) + ?.get(client.id) + ?.filter(msg => msg.namespace === namespace) .map(msg => { this.namespaceEventStreamSocket.get(namespace)?.nack(msg.batchNumber); nackedMessageIds.add(msg.id); }); - this.awaitingAck = this.awaitingAck.filter(msg => nackedMessageIds.has(msg.id)); + this.awaitingAck.delete(client.id); // If all clients for this namespace have disconnected, also close the connection to EVMConnect if (clientSet.size == 0) { @@ -189,8 +194,7 @@ export abstract class EventStreamProxyBase extends WebSocketEventsBase { }, batchNumber: batch.batchNumber, }; - this.awaitingAck.push(message); - this.send(namespace, JSON.stringify(message)); + this.send(namespace, message); } private async getSubscriptionName(ctx: Context, subId: string) { @@ -211,41 +215,49 @@ export abstract class EventStreamProxyBase extends WebSocketEventsBase { return undefined; } - @SubscribeMessage('ack') - handleAck(@MessageBody() data: AckMessageData) { + handleAck(client: WebSocketEx, data: AckMessageData) { if (data.id === undefined) { this.logger.error('Received malformed ack'); return; } - const inflight = this.awaitingAck.find(msg => msg.id === data.id); - this.logger.log(`Received ack ${data.id} inflight=${!!inflight}`); - if (this.namespaceEventStreamSocket !== undefined && inflight !== undefined) { - this.awaitingAck = this.awaitingAck.filter(msg => msg.id !== data.id); - if ( - // If nothing is left awaiting an ack - then we clearly need to ack - this.awaitingAck.length === 0 || - // Or if we have a batch number associated with this ID, then we can only ack if there - // are no other messages in-flight with the same batch number. - (inflight.batchNumber !== undefined && - !this.awaitingAck.find(msg => msg.batchNumber === inflight.batchNumber)) - ) { - this.logger.log(`In-flight batch complete (batchNumber=${inflight.batchNumber})`); - this.namespaceEventStreamSocket.get(inflight.namespace)?.ack(inflight.batchNumber); + let awaitingAck = this.awaitingAck.get(client.id); + + if (awaitingAck) { + const inflight = awaitingAck.find(msg => msg.id === data.id); + this.logger.log(`Received ack ${data.id} inflight=${!!inflight}`); + if (this.namespaceEventStreamSocket !== undefined && inflight !== undefined) { + // Remove the acked message id from the queue + awaitingAck = awaitingAck.filter(msg => msg.id !== data.id); + this.awaitingAck.set(client.id, awaitingAck); + if ( + // If nothing is left awaiting an ack - then we clearly need to ack + awaitingAck.length === 0 || + // Or if we have a batch number associated with this ID, then we can only ack if there + // are no other messages in-flight with the same batch number. + (inflight.batchNumber !== undefined && + !awaitingAck.filter(msg => msg.batchNumber === inflight.batchNumber)) + ) { + this.logger.log(`In-flight batch complete (batchNumber=${inflight.batchNumber})`); + this.namespaceEventStreamSocket.get(inflight.namespace)?.ack(inflight.batchNumber); + } } + } else { + this.logger.warn(`Received unrecognized ack from client ${client.id} for message ${data.id}`); } } - send(namespace, payload: string) { + send(namespace, payload: WebSocketMessageWithId) { const clients = this.namespaceClients.get(namespace); if (clients) { // Randomly select a connected client for this namespace to distribute load const selected = Math.floor(Math.random() * clients.size); let i = 0; - for (let client of clients.keys()) { + for (const client of clients.keys()) { if (i++ == selected) { - this.logger.debug(`WS <= ${payload}`); - client.send(payload); + this.awaitingAck.get(client.id)?.push(payload); + this.logger.verbose(`WS <= ${payload}`); + client.send(JSON.stringify(payload)); return; } } diff --git a/src/eventstream-proxy/eventstream-proxy.gateway.spec.ts b/src/eventstream-proxy/eventstream-proxy.gateway.spec.ts index becfe11..a650b4a 100644 --- a/src/eventstream-proxy/eventstream-proxy.gateway.spec.ts +++ b/src/eventstream-proxy/eventstream-proxy.gateway.spec.ts @@ -1,4 +1,4 @@ -// Copyright © 2022 Kaleido, Inc. +// Copyright © 2024 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // diff --git a/src/eventstream-proxy/eventstream-proxy.gateway.ts b/src/eventstream-proxy/eventstream-proxy.gateway.ts index 90e1a2b..c4e302d 100644 --- a/src/eventstream-proxy/eventstream-proxy.gateway.ts +++ b/src/eventstream-proxy/eventstream-proxy.gateway.ts @@ -1,4 +1,4 @@ -// Copyright © 2022 Kaleido, Inc. +// Copyright © 2024 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // diff --git a/src/eventstream-proxy/eventstream-proxy.interfaces.ts b/src/eventstream-proxy/eventstream-proxy.interfaces.ts index fe495d1..dbe6e2b 100644 --- a/src/eventstream-proxy/eventstream-proxy.interfaces.ts +++ b/src/eventstream-proxy/eventstream-proxy.interfaces.ts @@ -1,4 +1,4 @@ -// Copyright © 2022 Kaleido, Inc. +// Copyright © 2024 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // diff --git a/src/eventstream-proxy/eventstream-proxy.module.ts b/src/eventstream-proxy/eventstream-proxy.module.ts index 7a96d27..158a5e5 100644 --- a/src/eventstream-proxy/eventstream-proxy.module.ts +++ b/src/eventstream-proxy/eventstream-proxy.module.ts @@ -1,4 +1,4 @@ -// Copyright © 2022 Kaleido, Inc. +// Copyright © 2024 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // diff --git a/src/health/health.controller.spec.ts b/src/health/health.controller.spec.ts index 0277994..e732d2e 100644 --- a/src/health/health.controller.spec.ts +++ b/src/health/health.controller.spec.ts @@ -1,4 +1,4 @@ -// Copyright © 2022 Kaleido, Inc. +// Copyright © 2024 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // diff --git a/src/health/health.module.ts b/src/health/health.module.ts index 299008e..ba2d9e5 100644 --- a/src/health/health.module.ts +++ b/src/health/health.module.ts @@ -1,4 +1,4 @@ -// Copyright © 2022 Kaleido, Inc. +// Copyright © 2024 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // diff --git a/src/main.ts b/src/main.ts index f2ea0ee..9a1670f 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,4 +1,4 @@ -// Copyright © 2023 Kaleido, Inc. +// Copyright © 2024 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // diff --git a/src/request-context/request-id.middleware.ts b/src/request-context/request-id.middleware.ts index 7ad509b..a614f68 100644 --- a/src/request-context/request-id.middleware.ts +++ b/src/request-context/request-id.middleware.ts @@ -1,4 +1,4 @@ -// Copyright © 2022 Kaleido, Inc. +// Copyright © 2024 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // diff --git a/src/request-logging.interceptor.spec.ts b/src/request-logging.interceptor.spec.ts index 347ce32..31a8c6a 100644 --- a/src/request-logging.interceptor.spec.ts +++ b/src/request-logging.interceptor.spec.ts @@ -1,4 +1,4 @@ -// Copyright © 2021 Kaleido, Inc. +// Copyright © 2024 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // diff --git a/src/request-logging.interceptor.ts b/src/request-logging.interceptor.ts index d9c18e0..e790d5e 100644 --- a/src/request-logging.interceptor.ts +++ b/src/request-logging.interceptor.ts @@ -1,4 +1,4 @@ -// Copyright © 2021 Kaleido, Inc. +// Copyright © 2024 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // diff --git a/src/tokens/abimapper.service.ts b/src/tokens/abimapper.service.ts index 1601c25..aa2013f 100644 --- a/src/tokens/abimapper.service.ts +++ b/src/tokens/abimapper.service.ts @@ -1,4 +1,4 @@ -// Copyright © 2022 Kaleido, Inc. +// Copyright © 2024 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // diff --git a/src/tokens/blockchain.service.ts b/src/tokens/blockchain.service.ts index 8b36aeb..61b480e 100644 --- a/src/tokens/blockchain.service.ts +++ b/src/tokens/blockchain.service.ts @@ -1,4 +1,4 @@ -// Copyright © 2023 Kaleido, Inc. +// Copyright © 2024 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // diff --git a/src/tokens/erc1155.ts b/src/tokens/erc1155.ts index 0efd52c..ed401ae 100644 --- a/src/tokens/erc1155.ts +++ b/src/tokens/erc1155.ts @@ -1,4 +1,4 @@ -// Copyright © 2022 Kaleido, Inc. +// Copyright © 2024 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // diff --git a/src/tokens/erc165.ts b/src/tokens/erc165.ts index 62f4915..086d056 100644 --- a/src/tokens/erc165.ts +++ b/src/tokens/erc165.ts @@ -1,4 +1,4 @@ -// Copyright © 2022 Kaleido, Inc. +// Copyright © 2024 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // diff --git a/src/tokens/tokens.controller.spec.ts b/src/tokens/tokens.controller.spec.ts index 0874654..df698c7 100644 --- a/src/tokens/tokens.controller.spec.ts +++ b/src/tokens/tokens.controller.spec.ts @@ -1,4 +1,4 @@ -// Copyright © 2021 Kaleido, Inc. +// Copyright © 2024 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // diff --git a/src/tokens/tokens.controller.ts b/src/tokens/tokens.controller.ts index 3f00abe..af80fe4 100644 --- a/src/tokens/tokens.controller.ts +++ b/src/tokens/tokens.controller.ts @@ -1,4 +1,4 @@ -// Copyright © 2021 Kaleido, Inc. +// Copyright © 2024 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // @@ -48,7 +48,10 @@ import { TokensService } from './tokens.service'; @Controller() export class TokensController { - constructor(private service: TokensService, private blockchain: BlockchainConnectorService) {} + constructor( + private service: TokensService, + private blockchain: BlockchainConnectorService, + ) {} @Post('init') @HttpCode(204) diff --git a/src/tokens/tokens.interfaces.ts b/src/tokens/tokens.interfaces.ts index 1bb9778..749dc55 100644 --- a/src/tokens/tokens.interfaces.ts +++ b/src/tokens/tokens.interfaces.ts @@ -1,4 +1,4 @@ -// Copyright © 2021 Kaleido, Inc. +// Copyright © 2024 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // diff --git a/src/tokens/tokens.listener.ts b/src/tokens/tokens.listener.ts index 4d04277..af18610 100644 --- a/src/tokens/tokens.listener.ts +++ b/src/tokens/tokens.listener.ts @@ -1,4 +1,4 @@ -// Copyright © 2021 Kaleido, Inc. +// Copyright © 2024 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // diff --git a/src/tokens/tokens.module.ts b/src/tokens/tokens.module.ts index a28a406..aa2d616 100644 --- a/src/tokens/tokens.module.ts +++ b/src/tokens/tokens.module.ts @@ -1,4 +1,4 @@ -// Copyright © 2021 Kaleido, Inc. +// Copyright © 2024 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // diff --git a/src/tokens/tokens.service.spec.ts b/src/tokens/tokens.service.spec.ts index 631f9b6..7db6ec2 100644 --- a/src/tokens/tokens.service.spec.ts +++ b/src/tokens/tokens.service.spec.ts @@ -1,4 +1,4 @@ -// Copyright © 2023 Kaleido, Inc. +// Copyright © 2024 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // diff --git a/src/tokens/tokens.service.ts b/src/tokens/tokens.service.ts index bc70c9e..711ab6a 100644 --- a/src/tokens/tokens.service.ts +++ b/src/tokens/tokens.service.ts @@ -1,4 +1,4 @@ -// Copyright © 2021 Kaleido, Inc. +// Copyright © 2024 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // @@ -24,8 +24,7 @@ import { import { EventStreamService } from '../event-stream/event-stream.service'; import { EventStream, EventStreamSubscription } from '../event-stream/event-stream.interfaces'; import { EventStreamProxyGateway } from '../eventstream-proxy/eventstream-proxy.gateway'; -import { Context, newContext } from '../request-context/request-context.decorator'; -import { lastValueFrom } from 'rxjs'; +import { Context } from '../request-context/request-context.decorator'; import { AsyncResponse, CheckInterfaceRequest, @@ -50,7 +49,6 @@ import { packSubscriptionName, computeTokenId, unpackPoolLocator, - unpackSubscriptionName, packPoolLocator, } from './tokens.util'; import { TOKEN_STANDARD, TokenListener } from './tokens.listener'; @@ -64,6 +62,7 @@ import { TransferBatch, TransferSingle, } from './erc1155'; +import { eventStreamName } from '../utils'; export const BASE_SUBSCRIPTION_NAME = 'base'; @@ -81,7 +80,7 @@ export class TokensService { baseUrl: string; instancePath: string; topic: string; - stream: EventStream | undefined; + streamCache: Map = new Map(); constructor( private eventstream: EventStreamService, @@ -164,9 +163,19 @@ export class TokensService { } private async getStream(ctx: Context, namespace: string) { + let stream = this.streamCache.get(namespace); + if (stream !== undefined) { + return stream; + } await this.migrationCheck(ctx); - this.logger.log('Creating stream with name ' + `${this.topic}/${namespace}`); - return this.eventstream.createOrUpdateStream(ctx, `${this.topic}/${namespace}`, this.topic); + this.logger.log('Creating stream with name ' + eventStreamName(this.topic, namespace)); + stream = await this.eventstream.createOrUpdateStream( + ctx, + `${eventStreamName(this.topic, namespace)}`, + this.topic, + ); + this.streamCache.set(namespace, stream); + return stream; } /** @@ -192,7 +201,7 @@ export class TokensService { s.name === currentName || s.name === oldName1 || s.name === oldName2 || s.name === oldName3, ); for (const deprecatedStream of deprecatedStreams) { - this.logger.debug(`Purging deprecated eventstream '${deprecatedStream.id}'`); + this.logger.log(`Purging deprecated eventstream '${deprecatedStream.id}'`); await this.eventstream.deleteStream(ctx, deprecatedStream.id); } } diff --git a/src/tokens/tokens.util.spec.ts b/src/tokens/tokens.util.spec.ts index a6e5013..7f2587e 100644 --- a/src/tokens/tokens.util.spec.ts +++ b/src/tokens/tokens.util.spec.ts @@ -1,4 +1,4 @@ -// Copyright © 2021 Kaleido, Inc. +// Copyright © 2024 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // diff --git a/src/tokens/tokens.util.ts b/src/tokens/tokens.util.ts index 046e543..1a84337 100644 --- a/src/tokens/tokens.util.ts +++ b/src/tokens/tokens.util.ts @@ -1,4 +1,4 @@ -// Copyright © 2021 Kaleido, Inc. +// Copyright © 2024 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // diff --git a/src/utils.ts b/src/utils.ts index 2aa5db6..fbcadbc 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -69,3 +69,7 @@ export const getNestOptions = (): NestApplicationOptions => { } return options; }; + +export const eventStreamName = (topic: string, namespace: string) => { + return `${topic}/${namespace}`; +}; diff --git a/src/websocket-events/websocket-events.base.ts b/src/websocket-events/websocket-events.base.ts index 1908cc1..ebc5bfe 100644 --- a/src/websocket-events/websocket-events.base.ts +++ b/src/websocket-events/websocket-events.base.ts @@ -1,4 +1,4 @@ -// Copyright © 2022 Kaleido, Inc. +// Copyright © 2024 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // @@ -58,6 +58,10 @@ export interface WebSocketStart extends WebSocketActionBase { namespace: string; } +export interface WebSocketAck extends WebSocketActionBase { + id: string; +} + /** * Base class for websocket gateways. * @@ -69,7 +73,10 @@ export abstract class WebSocketEventsBase { @WebSocketServer() server: Server; - constructor(protected readonly logger: Logger, private requireAuth = false) {} + constructor( + protected readonly logger: Logger, + private requireAuth = false, + ) {} afterInit(server: Server) { const interval = setInterval(() => this.ping(), PING_INTERVAL); @@ -95,7 +102,7 @@ export abstract class WebSocketEventsBase this.logger.log(`WebSocket ${client.id}: error: ${err}`); }); client.on('message', msg => { - this.logger.debug(`WS => ${msg}`); + this.logger.verbose(`WS => ${msg}`); }); } diff --git a/test/app.e2e-spec.ts b/test/app.e2e-spec.ts index 5d6f0d6..7983201 100644 --- a/test/app.e2e-spec.ts +++ b/test/app.e2e-spec.ts @@ -1,4 +1,4 @@ -// Copyright © 2021 Kaleido, Inc. +// Copyright © 2024 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // diff --git a/test/suites/websocket.ts b/test/suites/websocket.ts index e5a0a8c..c093135 100644 --- a/test/suites/websocket.ts +++ b/test/suites/websocket.ts @@ -1,4 +1,4 @@ -// Copyright © 2021 Kaleido, Inc. +// Copyright © 2024 Kaleido, Inc. // // SPDX-License-Identifier: Apache-2.0 // @@ -129,7 +129,8 @@ export default (context: TestContext) => { }, }); return true; - }).close(); + }) + .close(); }); it('Token pool event from base subscription', () => { @@ -211,7 +212,8 @@ export default (context: TestContext) => { }, }); return true; - }).close(); + }) + .close(); }); it('Token pool event with old signature', () => { @@ -294,7 +296,8 @@ export default (context: TestContext) => { }, }); return true; - }).close(); + }) + .close(); }); it('Token mint event', async () => { @@ -392,7 +395,8 @@ export default (context: TestContext) => { }, }); return true; - }).close(); + }) + .close(); }); it('Token mint event with old pool ID', async () => { @@ -499,7 +503,8 @@ export default (context: TestContext) => { }, }); return true; - }).close(); + }) + .close(); expect(context.http.post).toHaveBeenCalledTimes(1); expect(context.http.post).toHaveBeenCalledWith( @@ -618,7 +623,8 @@ export default (context: TestContext) => { }, }); return true; - }).close(); + }) + .close(); expect(context.http.post).toHaveBeenCalledTimes(1); expect(context.http.post).toHaveBeenCalledWith( @@ -724,7 +730,8 @@ export default (context: TestContext) => { }, }); return true; - }).close(); + }) + .close(); expect(context.http.post).toHaveBeenCalledTimes(1); expect(context.http.post).toHaveBeenCalledWith( @@ -818,7 +825,8 @@ export default (context: TestContext) => { }, }); return true; - }).close(); + }) + .close(); }); it('Token transfer event from wrong pool', () => { @@ -883,7 +891,8 @@ export default (context: TestContext) => { expect(message.data.events[0].data.poolLocator).toEqual('id=N1&block=1'); expect(message.data.events[0].data.blockchain.info.blockNumber).toEqual('2'); return true; - }).close(); + }) + .close(); }); it('Token batch transfer', async () => { @@ -1015,7 +1024,8 @@ export default (context: TestContext) => { }, }); return true; - }).close(); + }) + .close(); expect(context.http.post).toHaveBeenCalledTimes(2); expect(context.http.post).toHaveBeenCalledWith( @@ -1060,7 +1070,8 @@ export default (context: TestContext) => { }, }); return true; - }).close(); + }) + .close(); }); it('Error receipt', () => { @@ -1093,7 +1104,8 @@ export default (context: TestContext) => { }, }); return true; - }).close(); + }) + .close(); }); it('Disconnect and reconnect', async () => { @@ -1161,6 +1173,7 @@ export default (context: TestContext) => { expect(message.data.events).toHaveLength(1); expect(message.data.events[0].event).toEqual('token-pool'); return true; - }).close(); + }) + .close(); }); };