fix: guard against empty lists before querying postgres (#1345)

This commit is contained in:
Rafael Cárdenas
2022-10-06 16:43:35 -05:00
committed by GitHub
parent 8709ea159f
commit 6c88a166c8
2 changed files with 45 additions and 28 deletions

View File

@@ -417,6 +417,12 @@ export class PgStore {
indexBlockHashValues.push(indexBytea, parentBytea);
blockHashValues.push(indexBytea);
});
if (blockHashValues.length === 0) {
return {
results: [],
total: 0,
};
}
// get txs in those blocks
const txs = await sql<{ tx_id: string; index_block_hash: string }[]>`
@@ -942,6 +948,9 @@ export class PgStore {
includeUnanchored: boolean;
includePruned?: boolean;
}): Promise<DbMempoolTx[]> {
if (args.txIds.length === 0) {
return [];
}
return this.sql.begin(async client => {
const result = await this.sql<MempoolTxQueryResult[]>`
SELECT ${unsafeCols(this.sql, [...MEMPOOL_TX_COLUMNS, abiColumn('mempool_txs')])}
@@ -1818,28 +1827,6 @@ export class PgStore {
return entries;
}
async getSmartContractList(contractIds: string[]) {
const result = await this.sql<
{
contract_id: string;
canonical: boolean;
tx_id: string;
block_height: number;
source_code: string;
abi: unknown | null;
}[]
>`
SELECT DISTINCT ON (contract_id) contract_id, canonical, tx_id, block_height, source_code, abi
FROM smart_contracts
WHERE contract_id IN ${contractIds}
ORDER BY contract_id DESC, abi != 'null' DESC, canonical DESC, microblock_canonical DESC, block_height DESC
`;
if (result.length === 0) {
[];
}
return result.map(r => parseQueryResultToSmartContract(r)).map(res => res.result);
}
async getSmartContract(contractId: string) {
const result = await this.sql<
{
@@ -2879,9 +2866,10 @@ export class PgStore {
const nftCustody = args.includeUnanchored
? this.sql(`nft_custody_unanchored`)
: this.sql(`nft_custody`);
const assetIdFilter = args.assetIdentifiers
? this.sql`AND nft.asset_identifier IN ${this.sql(args.assetIdentifiers)}`
: this.sql``;
const assetIdFilter =
args.assetIdentifiers && args.assetIdentifiers.length > 0
? this.sql`AND nft.asset_identifier IN ${this.sql(args.assetIdentifiers)}`
: this.sql``;
const nftTxResults = await this.sql<
(NftHoldingInfo & ContractTxQueryResult & { count: number })[]
>`
@@ -3122,7 +3110,10 @@ export class PgStore {
}: {
txIds: string[];
includeUnanchored: boolean;
}) {
}): Promise<DbTx[]> {
if (txIds.length === 0) {
return [];
}
return this.sql.begin(async sql => {
const maxBlockHeight = await this.getMaxBlockHeight(sql, { includeUnanchored });
const result = await sql<ContractTxQueryResult[]>`

View File

@@ -21,13 +21,14 @@ import {
DbNonFungibleTokenMetadata,
DbFungibleTokenMetadata,
} from '../datastore/common';
import { parseDbEvent } from '../api/controllers/db-controller';
import { getBlocksWithMetadata, parseDbEvent } from '../api/controllers/db-controller';
import * as assert from 'assert';
import { PgWriteStore } from '../datastore/pg-write-store';
import { cycleMigrations, runMigrations } from '../datastore/migrations';
import { getPostgres, PgSqlClient } from '../datastore/connection';
import { bnsNameCV, bufferToHexPrefixString, I32_MAX } from '../helpers';
import { ChainID, intCV, serializeCV } from '@stacks/transactions';
import { ChainID } from '@stacks/transactions';
import { TestBlockBuilder } from '../test-utils/test-builders';
function testEnvVars(
envVars: Record<string, string | undefined>,
@@ -4960,6 +4961,31 @@ describe('postgres datastore', () => {
if (query.found) expect(query.result).toStrictEqual(ftMetadata);
});
test('empty parameter lists are handled correctly', async () => {
const block = new TestBlockBuilder({ block_height: 1 }).addTx().build();
await db.update(block);
// Blocks with limit=0
await expect(getBlocksWithMetadata({ limit: 0, offset: 0, db: db })).resolves.not.toThrow();
// Mempool search with empty txIds
await expect(db.getMempoolTxs({ txIds: [], includeUnanchored: true })).resolves.not.toThrow();
// NFT holdings with empty asset identifier list
await expect(
db.getNftHoldings({
principal: 'S',
assetIdentifiers: [],
limit: 10,
offset: 0,
includeTxMetadata: false,
includeUnanchored: true,
})
).resolves.not.toThrow();
// Tx list details with empty txIds
await expect(
db.getTxListDetails({ txIds: [], includeUnanchored: true })
).resolves.not.toThrow();
});
afterEach(async () => {
await db?.close();
await runMigrations(undefined, 'down');