From 9e8959d45334fc08a31311b1a04e85f000e3cb80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Abadesso?= Date: Tue, 20 Aug 2024 09:46:53 -0300 Subject: [PATCH] fix: handle tx with no inputs (#181) * tests: added tests for the voidTransaction method * chore: re-add test_images_down * fix: markUtxosAsVoided should not throw when inputs are empty * fix: returning empty object on db utils and added test for services including db * tests: fix invalid order of calls --- packages/daemon/__tests__/db/index.test.ts | 6 ++ .../services/services_with_db.test.ts | 64 +++++++++++++++++++ packages/daemon/src/db/index.ts | 12 ++++ packages/daemon/src/utils/wallet.ts | 4 ++ 4 files changed, 86 insertions(+) create mode 100644 packages/daemon/__tests__/services/services_with_db.test.ts diff --git a/packages/daemon/__tests__/db/index.test.ts b/packages/daemon/__tests__/db/index.test.ts index a399a85d..de037f41 100644 --- a/packages/daemon/__tests__/db/index.test.ts +++ b/packages/daemon/__tests__/db/index.test.ts @@ -289,6 +289,12 @@ describe('tx output methods', () => { expect(countAfterDelete).toStrictEqual(0); }); + test('markUtxosAsVoided should not throw when utxos list is empty', async () => { + expect.hasAssertions(); + + await expect(markUtxosAsVoided(mysql, [])).resolves.not.toThrow(); + }); + test('getTxOutputsFromTx, getTxOutputs, getTxOutput', async () => { expect.hasAssertions(); diff --git a/packages/daemon/__tests__/services/services_with_db.test.ts b/packages/daemon/__tests__/services/services_with_db.test.ts new file mode 100644 index 00000000..33b7809e --- /dev/null +++ b/packages/daemon/__tests__/services/services_with_db.test.ts @@ -0,0 +1,64 @@ +/** + * Copyright (c) Hathor Labs and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import * as db from '../../src/db'; +import { handleVoidedTx } from '../../src/services'; +import { LRU } from '../../src/utils'; + +/** + * @jest-environment node + */ + +describe('handleVoidedTx (db)', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('should handle transactions with an empty list of inputs', async () => { + const voidTxSpy = jest.spyOn(db, 'voidTransaction'); + voidTxSpy.mockResolvedValue(); + + const context = { + socket: expect.any(Object), + healthcheck: expect.any(Object), + retryAttempt: expect.any(Number), + initialEventId: expect.any(Number), + txCache: expect.any(LRU), + event: { + stream_id: 'stream-id', + peer_id: 'peer_id', + network: 'testnet', + type: 'FULLNODE_EVENT', + latest_event_id: 4, + event: { + id: 5, + data: { + hash: 'random-hash', + outputs: [], + inputs: [], + tokens: [], + }, + }, + }, + }; + + const mysql = await db.getDbConnection(); + await expect(handleVoidedTx(context as any)).resolves.not.toThrow(); + + const lastEvent = await db.getLastSyncedEvent(mysql); + expect(db.voidTransaction).toHaveBeenCalledWith( + expect.any(Object), + 'random-hash', + expect.any(Object), + ); + expect(lastEvent).toStrictEqual({ + id: expect.any(Number), + last_event_id: 5, + updated_at: expect.any(String), + }); + }); +}); diff --git a/packages/daemon/src/db/index.ts b/packages/daemon/src/db/index.ts index 68e7c143..1367514d 100644 --- a/packages/daemon/src/db/index.ts +++ b/packages/daemon/src/db/index.ts @@ -1344,6 +1344,10 @@ export const markUtxosAsVoided = async ( ): Promise => { const txIds = utxos.map((tx) => tx.txId); + if (txIds.length === 0) { + return; + } + await mysql.query(` UPDATE \`tx_output\` SET \`voided\` = TRUE @@ -1409,6 +1413,10 @@ export const fetchAddressBalance = async ( mysql: MysqlConnection, addresses: string[], ): Promise => { + if (addresses.length === 0) { + return []; + } + const [results] = await mysql.query( `SELECT * FROM \`address_balance\` @@ -1439,6 +1447,10 @@ export const fetchAddressTxHistorySum = async ( mysql: MysqlConnection, addresses: string[], ): Promise => { + if (addresses.length === 0) { + return []; + } + const [results] = await mysql.query( `SELECT address, token_id, diff --git a/packages/daemon/src/utils/wallet.ts b/packages/daemon/src/utils/wallet.ts index 1ff43b1a..d9b6a34c 100644 --- a/packages/daemon/src/utils/wallet.ts +++ b/packages/daemon/src/utils/wallet.ts @@ -58,6 +58,10 @@ import { stringMapIterator } from './helpers'; * metadata. */ export const prepareOutputs = (outputs: EventTxOutput[], tokens: string[]): TxOutputWithIndex[] => { + if (outputs.length === 0) { + return []; + } + const preparedOutputs: [number, TxOutputWithIndex[]] = outputs.reduce( ([currIndex, newOutputs]: [number, TxOutputWithIndex[]], _output: EventTxOutput): [number, TxOutputWithIndex[]] => { const output = new Output(_output.value, Buffer.from(_output.script, 'base64'), {