fix: incorrect tx list returned for block result (#931)

This commit is contained in:
Matthew Little
2021-12-22 19:44:05 +01:00
committed by GitHub
parent 90c9b76e58
commit aab33a156a
3 changed files with 115 additions and 7 deletions

View File

@@ -2591,7 +2591,7 @@ export class PgDataStore
`
SELECT ${TX_COLUMNS}, ${abiColumn()}
FROM txs
WHERE index_block_hash = $1
WHERE index_block_hash = $1 AND canonical = true AND microblock_canonical = true
ORDER BY microblock_sequence DESC, tx_index DESC
`,
[hexToBuffer(block.result.index_block_hash)]
@@ -2833,7 +2833,7 @@ export class PgDataStore
`
SELECT tx_id, tx_index
FROM txs
WHERE index_block_hash = $1
WHERE index_block_hash = $1 AND canonical = true AND microblock_canonical = true
`,
[hexToBuffer(indexBlockHash)]
);

View File

@@ -67,6 +67,10 @@ interface TestBlockArgs {
block_hash?: string;
index_block_hash?: string;
burn_block_hash?: string;
parent_index_block_hash?: string;
parent_block_hash?: string;
parent_microblock_hash?: string;
parent_microblock_sequence?: number;
}
/**
@@ -78,16 +82,16 @@ function testBlock(args?: TestBlockArgs): DbBlock {
return {
block_hash: args?.block_hash ?? BLOCK_HASH,
index_block_hash: args?.index_block_hash ?? INDEX_BLOCK_HASH,
parent_index_block_hash: '',
parent_block_hash: '',
parent_microblock_hash: '',
parent_index_block_hash: args?.parent_index_block_hash ?? '',
parent_block_hash: args?.parent_block_hash ?? '',
parent_microblock_hash: args?.parent_microblock_hash ?? '',
parent_microblock_sequence: args?.parent_microblock_sequence ?? 0,
block_height: args?.block_height ?? BLOCK_HEIGHT,
burn_block_time: BURN_BLOCK_TIME,
burn_block_hash: args?.burn_block_hash ?? BURN_BLOCK_HASH,
burn_block_height: BURN_BLOCK_HEIGHT,
miner_txid: '0x4321',
canonical: true,
parent_microblock_sequence: 0,
execution_cost_read_count: 0,
execution_cost_read_length: 0,
execution_cost_runtime: 0,

View File

@@ -53,7 +53,11 @@ import { PoolClient } from 'pg';
import { bufferToHexPrefixString, I32_MAX, microStxToStx, STACKS_DECIMAL_PLACES } from '../helpers';
import { FEE_RATE } from './../api/routes/fee-rate';
import { Block, FeeRateRequest } from 'docs/generated';
import { TestBlockBuilder, testMempoolTx } from '../test-utils/test-builders';
import {
TestBlockBuilder,
testMempoolTx,
TestMicroblockStreamBuilder,
} from '../test-utils/test-builders';
describe('api tests', () => {
let db: PgDataStore;
@@ -6786,6 +6790,106 @@ describe('api tests', () => {
expect(JSON.parse(fetchBlockByInvalidBurnBlockHash.text)).toEqual(expectedResp4);
});
test('block tx list excludes non-canonical', async () => {
const block1 = new TestBlockBuilder({ block_hash: '0x0001', index_block_hash: '0x0001' })
.addTx({ tx_id: '0x0001' })
.build();
await db.update(block1);
const microblock1 = new TestMicroblockStreamBuilder()
.addMicroblock({
microblock_sequence: 0,
microblock_hash: '0xff01',
microblock_parent_hash: '0x1212',
parent_index_block_hash: block1.block.index_block_hash,
})
.addTx({ tx_id: '0x1001', index_block_hash: '0x0002' })
.build();
await db.updateMicroblocks(microblock1);
const microblock2 = new TestMicroblockStreamBuilder()
.addMicroblock({
microblock_sequence: 1,
microblock_hash: '0xff02',
microblock_parent_hash: microblock1.microblocks[0].microblock_hash,
parent_index_block_hash: block1.block.index_block_hash,
})
.addTx({ tx_id: '0x1002', index_block_hash: '0x0002' })
.build();
await db.updateMicroblocks(microblock2);
const expectedResp1 = {
burn_block_hash: '0xf44f44',
burn_block_height: expect.any(Number),
burn_block_time: expect.any(Number),
burn_block_time_iso: expect.any(String),
canonical: true,
execution_cost_read_count: 0,
execution_cost_read_length: 0,
execution_cost_runtime: 0,
execution_cost_write_count: 0,
execution_cost_write_length: 0,
hash: '0x0001',
height: 1,
microblocks_accepted: [],
microblocks_streamed: [
microblock2.microblocks[0].microblock_hash,
microblock1.microblocks[0].microblock_hash,
],
miner_txid: '0x4321',
parent_block_hash: '',
parent_microblock_hash: '',
parent_microblock_sequence: 0,
txs: ['0x0001'],
};
const fetch1 = await supertest(api.server).get(
`/extended/v1/block/by_height/${block1.block.block_height}`
);
expect(fetch1.status).toBe(200);
expect(fetch1.type).toBe('application/json');
expect(JSON.parse(fetch1.text)).toEqual(expectedResp1);
// Confirm the first microblock, but orphan the second
const block2 = new TestBlockBuilder({
block_height: block1.block.block_height + 1,
block_hash: '0x0002',
index_block_hash: '0x0002',
parent_block_hash: block1.block.block_hash,
parent_index_block_hash: block1.block.index_block_hash,
parent_microblock_hash: microblock1.microblocks[0].microblock_hash,
parent_microblock_sequence: microblock1.microblocks[0].microblock_sequence,
})
.addTx({ tx_id: microblock1.txs[0].tx.tx_id })
.addTx({ tx_id: '0x0002' })
.build();
await db.update(block2);
const fetch2 = await supertest(api.server).get(
`/extended/v1/block/by_height/${block2.block.block_height}`
);
const expectedResp2 = {
burn_block_hash: '0xf44f44',
burn_block_height: expect.any(Number),
burn_block_time: expect.any(Number),
burn_block_time_iso: expect.any(String),
canonical: true,
execution_cost_read_count: 0,
execution_cost_read_length: 0,
execution_cost_runtime: 0,
execution_cost_write_count: 0,
execution_cost_write_length: 0,
hash: '0x0002',
height: 2,
microblocks_accepted: [microblock1.microblocks[0].microblock_hash],
microblocks_streamed: [],
miner_txid: '0x4321',
parent_block_hash: '0x0001',
parent_microblock_hash: microblock1.microblocks[0].microblock_hash,
parent_microblock_sequence: microblock1.microblocks[0].microblock_sequence,
// Ensure micro-orphaned tx `0x1002` is not included
txs: ['0x1001', '0x0002'],
};
expect(fetch2.status).toBe(200);
expect(fetch2.type).toBe('application/json');
expect(JSON.parse(fetch2.text)).toEqual(expectedResp2);
});
test('tx - sponsored', async () => {
const dbBlock: DbBlock = {
block_hash: '0xff',