Skip to content

Commit

Permalink
Avoid double emitting of the created event for token transfers
Browse files Browse the repository at this point in the history
  • Loading branch information
skubarenko committed Feb 21, 2024
1 parent 4833208 commit a9b17d7
Showing 1 changed file with 48 additions and 8 deletions.
56 changes: 48 additions & 8 deletions src/tokenBridge/tokenBridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ interface TokenBridgeComponentsEvents {
}

export class TokenBridge implements Disposable {
private static readonly defaultLastCreatedTokenTransfersTimerPeriod = 60_000;
private static readonly defaultLastCreatedTokenTransferLifetime = 30_000;

readonly data: TokenBridgeDataApi;
readonly stream: TokenBridgeStreamApi;
readonly bridgeComponents: TokenBridgeComponents;
Expand All @@ -59,6 +62,8 @@ export class TokenBridge implements Disposable {
}>
>();

private readonly lastCreatedTokenTransfers: Map<string, readonly [tokenTransfer: BridgeTokenTransfer, addedTime: number]> = new Map();
private lastCreatedTokenTransfersTimerId: ReturnType<typeof setInterval> | undefined;
private _isDisposed = false;

constructor(options: TokenBridgeOptions) {
Expand Down Expand Up @@ -250,7 +255,7 @@ export class TokenBridge implements Disposable {
loggerProvider.lazyLogger.log?.(getBridgeTokenTransferLogMessage(depositOperation.tokenTransfer));
loggerProvider.lazyLogger.debug?.(getDetailedBridgeTokenTransferLogMessage(depositOperation.tokenTransfer));

this.emitLocalTokenTransferCreated(depositOperation.tokenTransfer);
this.emitLocalTokenTransferCreatedEvent(depositOperation.tokenTransfer);

return depositOperation;
}
Expand Down Expand Up @@ -309,7 +314,7 @@ export class TokenBridge implements Disposable {
}
};

this.emitLocalTokenTransferCreated(bridgeTokenWithdrawal);
this.emitLocalTokenTransferCreatedEvent(bridgeTokenWithdrawal);

return {
tokenTransfer: bridgeTokenWithdrawal,
Expand Down Expand Up @@ -360,6 +365,8 @@ export class TokenBridge implements Disposable {

this.rejectAndClearAllStatusWatchers('The TokenBridge has been stopped!');
this.detachEvents();
clearInterval(this.lastCreatedTokenTransfersTimerId);
this.lastCreatedTokenTransfers.clear();

this._isDisposed = true;
}
Expand Down Expand Up @@ -468,14 +475,30 @@ export class TokenBridge implements Disposable {

// #endregion

protected emitLocalTokenTransferCreated(tokenTransfer: TokenTransferCreatedEventArgument[0]) {
protected emitLocalTokenTransferCreatedEvent(tokenTransfer: TokenTransferCreatedEventArgument[0]) {
setTimeout(() => {
loggerProvider.logger.log('Emitting the tokenTransferCreated event...');
(this.events.tokenTransferCreated as ToEventEmitter<typeof this.events.tokenTransferCreated>).emit(tokenTransfer);
loggerProvider.logger.log('The tokenTransferCreated event has been emitted');
this.emitTokenTransferCreatedOrUpdatedEvent(tokenTransfer);
}, 0);
}

protected emitTokenTransferCreatedOrUpdatedEvent(tokenTransfer: TokenTransferCreatedEventArgument[0]) {
this.ensureLastCreatedTokenTransfersTimerIsStarted();

const initialOperationHash = bridgeUtils.getInitialOperationHash(tokenTransfer);
let eventName: 'tokenTransferCreated' | 'tokenTransferUpdated';
if (this.lastCreatedTokenTransfers.has(initialOperationHash)) {
eventName = 'tokenTransferUpdated';
}
else {
eventName = 'tokenTransferCreated';
this.lastCreatedTokenTransfers.set(initialOperationHash, [tokenTransfer, Date.now()]);
}

loggerProvider.logger.log(`Emitting the ${eventName} event...`);
(this.events[eventName] as ToEventEmitter<typeof this.events[typeof eventName]>).emit(tokenTransfer);
loggerProvider.logger.log(`The ${eventName} event has been emitted`);
}

protected resolveStatusWatcherIfNeeded(tokenTransfer: BridgeTokenTransfer) {
const initialOperationHash = bridgeUtils.getInitialOperationHash(tokenTransfer);
const statusWatchers = this.tokenTransferOperationWatchers.get(initialOperationHash);
Expand Down Expand Up @@ -516,12 +539,12 @@ export class TokenBridge implements Disposable {
}

protected handleTransfersBridgeDataProviderTokenTransferCreated = (createdTokenTransfer: TokenTransferCreatedEventArgument[0]) => {
(this.events.tokenTransferCreated as ToEventEmitter<typeof this.events.tokenTransferCreated>).emit(createdTokenTransfer);
this.resolveStatusWatcherIfNeeded(createdTokenTransfer);
this.emitTokenTransferCreatedOrUpdatedEvent(createdTokenTransfer);
};

protected handleTransfersBridgeDataProviderTokenTransferUpdated = (updatedTokenTransfer: BridgeTokenTransfer) => {
this.resolveStatusWatcherIfNeeded(updatedTokenTransfer);

(this.events.tokenTransferUpdated as ToEventEmitter<typeof this.events.tokenTransferUpdated>).emit(updatedTokenTransfer);
};

Expand Down Expand Up @@ -619,6 +642,23 @@ export class TokenBridge implements Disposable {
};
}

private ensureLastCreatedTokenTransfersTimerIsStarted() {
if (this.lastCreatedTokenTransfersTimerId)
return;

this.lastCreatedTokenTransfersTimerId = setInterval(
() => {
const currentTime = Date.now();
for (const entry of this.lastCreatedTokenTransfers) {
if (currentTime - entry[1][1] > TokenBridge.defaultLastCreatedTokenTransferLifetime) {
this.lastCreatedTokenTransfers.delete(entry[0]);
}
}
},
TokenBridge.defaultLastCreatedTokenTransfersTimerPeriod
);
}

private async getTezosTicketerContent(tezosTicketerAddress: string): Promise<string> {
const storage = await this.tezosToolkit.contract.getStorage<{ content: any }>(tezosTicketerAddress);
const content = [...Object.values(storage.content)];
Expand Down

0 comments on commit a9b17d7

Please sign in to comment.