Skip to content

Commit

Permalink
Handle signers rotated event and updates.
Browse files Browse the repository at this point in the history
  • Loading branch information
raress96 committed Nov 15, 2024
1 parent 20cb777 commit 7ca3b38
Show file tree
Hide file tree
Showing 12 changed files with 478 additions and 62 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ export class ApprovalsProcessorService {
response.remainingGasBalance.amount,
);

// TODO: Handle retries in case of transaction failing?
// If transaction generation fails, the task will be retried in parent function
const txHash = await this.transactionsHelper.signAndSendTransactionAndGetNonce(transaction, this.walletSigner);

this.logger.debug(`Processed refund for ${response.message.messageID}, sent transaction ${txHash}`);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ describe('ApprovalsProcessorService', () => {
} as RefundTask,
id: 'lastUUID1',
timestamp: '1234',
chain: 'multiversx',
},
];
}
Expand Down Expand Up @@ -159,6 +160,7 @@ describe('ApprovalsProcessorService', () => {
} as GatewayTransactionTask,
id: 'UUID',
timestamp: '1234',
chain: 'multiversx',
},
],
},
Expand Down Expand Up @@ -235,6 +237,7 @@ describe('ApprovalsProcessorService', () => {
} as ExecuteTask,
id: 'UUID',
timestamp: '1234',
chain: 'multiversx',
},
],
},
Expand Down Expand Up @@ -281,6 +284,7 @@ describe('ApprovalsProcessorService', () => {
} as ExecuteTask,
id: 'UUID',
timestamp: '1234',
chain: 'multiversx',
},
],
},
Expand Down Expand Up @@ -308,6 +312,7 @@ describe('ApprovalsProcessorService', () => {
} as GatewayTransactionTask,
id: 'UUID',
timestamp: '1234',
chain: 'multiversx',
},
],
},
Expand Down Expand Up @@ -360,6 +365,7 @@ describe('ApprovalsProcessorService', () => {
} as VerifyTask,
id: 'UUID',
timestamp: '1234',
chain: 'multiversx',
},
],
},
Expand Down Expand Up @@ -616,6 +622,7 @@ describe('ApprovalsProcessorService', () => {
} as RefundTask,
id: 'UUID',
timestamp: '1234',
chain: 'multiversx',
},
],
},
Expand Down Expand Up @@ -663,6 +670,7 @@ describe('ApprovalsProcessorService', () => {
} as RefundTask,
id: 'UUID',
timestamp: '1234',
chain: 'multiversx',
},
],
},
Expand Down Expand Up @@ -716,6 +724,7 @@ describe('ApprovalsProcessorService', () => {
} as RefundTask,
id: 'UUID',
timestamp: '1234',
chain: 'multiversx',
},
],
},
Expand Down Expand Up @@ -767,6 +776,7 @@ describe('ApprovalsProcessorService', () => {
} as RefundTask,
id: 'UUID',
timestamp: '1234',
chain: 'multiversx',
},
],
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
ContractCallEvent,
MessageApprovedEvent,
MessageExecutedEvent,
WeightedSigners,
SignersRotatedEvent,
} from '@mvx-monorepo/common/contracts/entities/gateway-events';
import { TransactionEvent, TransactionOnNetwork } from '@multiversx/sdk-network-providers/out';
import { MessageApprovedRepository } from '@mvx-monorepo/common/database/repository/message-approved.repository';
Expand All @@ -19,6 +19,7 @@ import BigNumber from 'bignumber.js';
import CallEvent = Components.Schemas.CallEvent;
import MessageApprovedEventApi = Components.Schemas.MessageApprovedEvent;
import MessageExecutedEventApi = Components.Schemas.MessageExecutedEvent;
import SignersRotatedEventApi = Components.Schemas.SignersRotatedEvent;

const mockGatewayContract = 'erd1qqqqqqqqqqqqqpgqvc7gdl0p4s97guh498wgz75k8sav6sjfjlwqh679jy';

Expand Down Expand Up @@ -48,7 +49,9 @@ describe('GatewayProcessor', () => {
sourceChain: 'ethereum',
messageId: 'messageId',
};
const weightedSigners: WeightedSigners = {
const signersRotatedEvent: SignersRotatedEvent = {
epoch: new BigNumber(1),
signersHash: '0c38359b7a35c755573659d797afec315bb0e51374a056745abd9764715a15da',
signers: [
{
signer: '',
Expand Down Expand Up @@ -314,13 +317,30 @@ describe('GatewayProcessor', () => {
});

it('Should handle event', async () => {
gatewayContract.decodeSignersRotatedEvent.mockReturnValueOnce(weightedSigners);
gatewayContract.decodeSignersRotatedEvent.mockReturnValueOnce(signersRotatedEvent);

const result = await service.handleGatewayEvent(rawEvent, createMock(), 0, '100', '0');
const transaction = createMock<TransactionOnNetwork>();
transaction.hash = 'txHash';
transaction.sender = Address.newFromBech32('erd1qqqqqqqqqqqqqpgqzqvm5ywqqf524efwrhr039tjs29w0qltkklsa05pk7');

const result = await service.handleGatewayEvent(rawEvent, transaction, 0, '100', '0');

expect(gatewayContract.decodeSignersRotatedEvent).toHaveBeenCalledTimes(1);

expect(result).toEqual(undefined);
expect(result).not.toBeUndefined();
expect(result?.type).toBe('SIGNERS_ROTATED');

const event = result as SignersRotatedEventApi;

expect(event.eventID).toBe('0xtxHash-0');
expect(event.messageID).toBe('0xtxHash-0');
expect(event.meta).toEqual({
txID: 'txHash',
fromAddress: 'erd1qqqqqqqqqqqqqpgqzqvm5ywqqf524efwrhr039tjs29w0qltkklsa05pk7',
finalized: true,
epoch: 1,
signersHash: BinaryUtils.hexToBase64('0c38359b7a35c755573659d797afec315bb0e51374a056745abd9764715a15da'),
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import MessageApprovedEvent = Components.Schemas.MessageApprovedEvent;
import Event = Components.Schemas.Event;
import MessageExecutedEvent = Components.Schemas.MessageExecutedEvent;
import BigNumber from 'bignumber.js';
import SignersRotatedEvent = Components.Schemas.SignersRotatedEvent;

@Injectable()
export class GatewayProcessor {
Expand Down Expand Up @@ -55,7 +56,7 @@ export class GatewayProcessor {
}

if (rawEvent.identifier === EventIdentifiers.ROTATE_SIGNERS && eventName === Events.SIGNERS_ROTATED_EVENT) {
return this.handleSignersRotatedEvent(rawEvent, transaction.hash, index);
return this.handleSignersRotatedEvent(rawEvent, transaction.sender.bech32(), transaction.hash, index);
}

return undefined;
Expand Down Expand Up @@ -169,7 +170,7 @@ export class GatewayProcessor {
fromAddress: sender,
finalized: true,
},
status: 'SUCCESSFUL', // TODO: How to handle reverted?
status: 'SUCCESSFUL',
};

this.logger.debug(
Expand All @@ -182,46 +183,30 @@ export class GatewayProcessor {
};
}

// TODO: Properly implement this after the Axelar GMP API supports it
private handleSignersRotatedEvent(rawEvent: ITransactionEvent, txHash: string, index: number) {
const weightedSigners = this.gatewayContract.decodeSignersRotatedEvent(rawEvent);
private handleSignersRotatedEvent(rawEvent: ITransactionEvent, sender: string, txHash: string, index: number): Event {
const signersRotatedEvent = this.gatewayContract.decodeSignersRotatedEvent(rawEvent);

this.logger.warn(
`Received Signers Rotated event which is not properly implemented yet. Transaction: ${txHash}, index: ${index}`,
weightedSigners,
);
const signersRotated: SignersRotatedEvent = {
eventID: DecodingUtils.getEventId(txHash, index),
messageID: DecodingUtils.getEventId(txHash, index),
meta: {
txID: txHash,
fromAddress: sender,
finalized: true,
signersHash: BinaryUtils.hexToBase64(signersRotatedEvent.signersHash),
epoch: signersRotatedEvent.epoch.toNumber(),
},
};

return undefined;
this.logger.debug(
`Successfully handled signers rotated event from transaction ${txHash}, log index ${index}`,
signersRotated,
signersRotatedEvent,
);

// // The id needs to have `0x` in front of the txHash (hex string)
// const id = `0x${txHash}-${index}`;
//
//
// // @ts-ignore
// const response = await this.axelarGmpApi.verifyVerifierSet(
// id,
// weightedSigners.signers,
// weightedSigners.threshold,
// weightedSigners.nonce,
// );

// if (response.published) {
// return;
// }
//
// this.logger.warn(`Couldn't dispatch verifyWorkerSet ${id} to Amplifier API. Retrying...`);
//
// setTimeout(async () => {
// const response = await this.axelarGmpApi.verifyVerifierSet(
// id,
// weightedSigners.signers,
// weightedSigners.threshold,
// weightedSigners.nonce,
// );
//
// if (!response.published) {
// this.logger.error(`Couldn't dispatch verifyWorkerSet ${id} to Amplifier API.`);
// }
// }, 60_000);
return {
type: 'SIGNERS_ROTATED',
...signersRotated,
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ export class GasCheckerService {
}

private async checkGasServiceFees() {
// TODO: Add support for other tokens also
const tokens = await this.getAccountEgldAndWegld(this.gasServiceContract.getContractAddress());
const tokensToCollect = Object.values(tokens)
.filter((token) => token.balance.gte(EGLD_COLLECT_THRESHOLD))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,14 @@ import { ApiConfigService, AxelarGmpApi } from '@mvx-monorepo/common';
import { ItsContract } from '@mvx-monorepo/common/contracts/its.contract';
import { Locker } from '@multiversx/sdk-nestjs-common';
import { GasError } from '@mvx-monorepo/common/contracts/entities/gas.error';
import { CannotExecuteMessageEvent, Event } from '@mvx-monorepo/common/api/entities/axelar.gmp.api';
import {
CannotExecuteMessageEvent,

Check failure on line 22 in apps/mvx-event-processor/src/message-approved-processor/message-approved.processor.service.ts

View workflow job for this annotation

GitHub Actions / test (18.x)

'CannotExecuteMessageEvent' is defined but never used
CannotExecuteMessageEventV2,
Event,
} from '@mvx-monorepo/common/api/entities/axelar.gmp.api';
import { AxiosError } from 'axios';
import { DecodingUtils } from '@mvx-monorepo/common/utils/decoding.utils';
import { CONSTANTS } from '@mvx-monorepo/common/utils/constants.enum';

// Support a max of 3 retries (mainly because some Interchain Token Service endpoints need to be called 2 times)
const MAX_NUMBER_OF_RETRIES: number = 3;
Expand Down Expand Up @@ -202,11 +208,17 @@ export class MessageApprovedProcessorService {

messageApproved.status = MessageApprovedStatus.FAILED;

const cannotExecuteEvent: CannotExecuteMessageEvent = {
eventID: messageApproved.messageId,
taskItemID: messageApproved.taskItemId || '',
const cannotExecuteEvent: CannotExecuteMessageEventV2 = {
eventID: messageApproved.executeTxHash
? DecodingUtils.getEventId(messageApproved.executeTxHash, 0)
: messageApproved.messageId,
messageID: messageApproved.messageId,
sourceChain: CONSTANTS.SOURCE_CHAIN_NAME,
reason: 'ERROR',
details: '',
meta: {
taskItemID: messageApproved.taskItemId || '',
},
};

try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -246,9 +246,13 @@ describe('MessageApprovedProcessorService', () => {
expect(axelarGmpApi.postEvents.mock.lastCall[0][0]).toEqual({
type: 'CANNOT_EXECUTE_MESSAGE',
eventID: originalSecondEntry.messageId,
taskItemID: originalSecondEntry.taskItemId,
messageID: originalSecondEntry.messageId,
sourceChain: 'multiversx',
reason: 'ERROR',
details: '',
meta: {
taskItemID: originalSecondEntry.taskItemId,
},
});

// Was not updated
Expand Down
Loading

0 comments on commit 7ca3b38

Please sign in to comment.