mirror of
https://github.com/alexgo-io/stacks-blockchain-api.git
synced 2026-01-12 16:53:19 +08:00
feat: add transaction_count for microblocks_accepted in block (#1162)
* feat: added transaction_count for block * refactor: added microblock_tx_count in block * refactor: removed unecessary type * docs: updated block.example.json * refactor: rebased with develop * refactor: moved initializations with declarations
This commit is contained in:
@@ -30,5 +30,10 @@
|
||||
"execution_cost_read_length": 1659409,
|
||||
"execution_cost_runtime": 2520952000,
|
||||
"execution_cost_write_count": 608,
|
||||
"execution_cost_write_length": 80170
|
||||
"execution_cost_write_length": 80170,
|
||||
"microblock_tx_count": {
|
||||
"0xce0b1a4099d3fc7d5885cc7a3baa952b6d999f9709d0683b98b843597208231c": 5,
|
||||
"0x4c0529b6448a5885991c5021bd869cc97f1692c128a98b382729dc962203c326": 6,
|
||||
"0x64968846291dfea1015228a9d4bbd60aac81378cd6774b810b08e59e6b0e7494": 9
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,8 @@
|
||||
"execution_cost_read_length",
|
||||
"execution_cost_runtime",
|
||||
"execution_cost_write_count",
|
||||
"execution_cost_write_length"
|
||||
"execution_cost_write_length",
|
||||
"microblock_tx_count"
|
||||
],
|
||||
"properties": {
|
||||
"canonical": {
|
||||
@@ -112,6 +113,13 @@
|
||||
"execution_cost_write_length": {
|
||||
"type": "integer",
|
||||
"description": "Execution cost write length."
|
||||
},
|
||||
"microblock_tx_count": {
|
||||
"type": "object",
|
||||
"description": "List of txs counts in each accepted microblock",
|
||||
"additionalProperties": {
|
||||
"type": "number"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
6
docs/generated.d.ts
vendored
6
docs/generated.d.ts
vendored
@@ -1288,6 +1288,12 @@ export interface Block {
|
||||
* Execution cost write length.
|
||||
*/
|
||||
execution_cost_write_length: number;
|
||||
/**
|
||||
* List of txs counts in each accepted microblock
|
||||
*/
|
||||
microblock_tx_count: {
|
||||
[k: string]: number | undefined;
|
||||
};
|
||||
[k: string]: unknown | undefined;
|
||||
}
|
||||
/**
|
||||
|
||||
@@ -446,7 +446,8 @@ export async function getBlockFromDataStore({
|
||||
result.block,
|
||||
result.txs.map(tx => tx.tx_id),
|
||||
result.microblocks.accepted.map(mb => mb.microblock_hash),
|
||||
result.microblocks.streamed.map(mb => mb.microblock_hash)
|
||||
result.microblocks.streamed.map(mb => mb.microblock_hash),
|
||||
result.microblock_tx_count
|
||||
);
|
||||
return { found: true, result: apiBlock };
|
||||
}
|
||||
@@ -455,7 +456,8 @@ function parseDbBlock(
|
||||
dbBlock: DbBlock,
|
||||
txIds: string[],
|
||||
microblocksAccepted: string[],
|
||||
microblocksStreamed: string[]
|
||||
microblocksStreamed: string[],
|
||||
microblock_tx_count: Record<string, number>
|
||||
): Block {
|
||||
const apiBlock: Block = {
|
||||
canonical: dbBlock.canonical,
|
||||
@@ -479,6 +481,7 @@ function parseDbBlock(
|
||||
execution_cost_runtime: dbBlock.execution_cost_runtime,
|
||||
execution_cost_write_count: dbBlock.execution_cost_write_count,
|
||||
execution_cost_write_length: dbBlock.execution_cost_write_length,
|
||||
microblock_tx_count,
|
||||
};
|
||||
return apiBlock;
|
||||
}
|
||||
@@ -1074,7 +1077,8 @@ export async function searchHashWithMetadata(
|
||||
blockQuery.result.block,
|
||||
blockQuery.result.txs.map(tx => tx.tx_id),
|
||||
blockQuery.result.microblocks.accepted.map(mb => mb.microblock_hash),
|
||||
blockQuery.result.microblocks.streamed.map(mb => mb.microblock_hash)
|
||||
blockQuery.result.microblocks.streamed.map(mb => mb.microblock_hash),
|
||||
blockQuery.result.microblock_tx_count
|
||||
);
|
||||
return {
|
||||
found: true,
|
||||
|
||||
@@ -506,6 +506,7 @@ export interface DbGetBlockWithMetadataResponse<
|
||||
microblocks: TWithMicroblocks extends true
|
||||
? { accepted: DbMicroblock[]; streamed: DbMicroblock[] }
|
||||
: null;
|
||||
microblock_tx_count: Record<string, number>;
|
||||
}
|
||||
|
||||
export interface DbRawEventRequest {
|
||||
|
||||
@@ -218,8 +218,9 @@ export class PgStore {
|
||||
return { found: false };
|
||||
}
|
||||
let txs: DbTx[] | null = null;
|
||||
let microblocksAccepted: DbMicroblock[] | null = null;
|
||||
let microblocksStreamed: DbMicroblock[] | null = null;
|
||||
const microblocksAccepted: DbMicroblock[] = [];
|
||||
const microblocksStreamed: DbMicroblock[] = [];
|
||||
const microblock_tx_count: Record<string, number> = {};
|
||||
if (metadata?.txs) {
|
||||
const txQuery = await sql<ContractTxQueryResult[]>`
|
||||
SELECT ${unsafeCols(sql, [...TX_COLUMNS, abiColumn()])}
|
||||
@@ -231,21 +232,32 @@ export class PgStore {
|
||||
txs = txQuery.map(r => parseTxQueryResult(r));
|
||||
}
|
||||
if (metadata?.microblocks) {
|
||||
const microblocksQuery = await sql<MicroblockQueryResult[]>`
|
||||
SELECT ${sql(MICROBLOCK_COLUMNS)}
|
||||
const microblocksQuery = await sql<
|
||||
(MicroblockQueryResult & { transaction_count: number })[]
|
||||
>`
|
||||
SELECT ${sql(MICROBLOCK_COLUMNS)}, (
|
||||
SELECT COUNT(tx_id)::integer as transaction_count
|
||||
FROM txs
|
||||
WHERE txs.microblock_hash = microblocks.microblock_hash
|
||||
AND canonical = true AND microblock_canonical = true
|
||||
)
|
||||
FROM microblocks
|
||||
WHERE parent_index_block_hash
|
||||
IN ${sql([block.result.index_block_hash, block.result.parent_index_block_hash])}
|
||||
AND microblock_canonical = true
|
||||
ORDER BY microblock_sequence DESC
|
||||
`;
|
||||
const parsedMicroblocks = microblocksQuery.map(r => parseMicroblockQueryResult(r));
|
||||
microblocksAccepted = parsedMicroblocks.filter(
|
||||
mb => mb.parent_index_block_hash === block.result.parent_index_block_hash
|
||||
);
|
||||
microblocksStreamed = parsedMicroblocks.filter(
|
||||
mb => mb.parent_index_block_hash === block.result.index_block_hash
|
||||
);
|
||||
for (const mb of microblocksQuery) {
|
||||
const parsedMicroblock = parseMicroblockQueryResult(mb);
|
||||
const count = mb.transaction_count;
|
||||
if (parsedMicroblock.parent_index_block_hash === block.result.parent_index_block_hash) {
|
||||
microblocksAccepted.push(parsedMicroblock);
|
||||
microblock_tx_count[parsedMicroblock.microblock_hash] = count;
|
||||
}
|
||||
if (parsedMicroblock.parent_index_block_hash === block.result.index_block_hash) {
|
||||
microblocksStreamed.push(parsedMicroblock);
|
||||
}
|
||||
}
|
||||
}
|
||||
type ResultType = DbGetBlockWithMetadataResponse<TWithTxs, TWithMicroblocks>;
|
||||
const result: ResultType = {
|
||||
@@ -255,6 +267,7 @@ export class PgStore {
|
||||
accepted: microblocksAccepted,
|
||||
streamed: microblocksStreamed,
|
||||
} as ResultType['microblocks'],
|
||||
microblock_tx_count,
|
||||
};
|
||||
return {
|
||||
found: true,
|
||||
|
||||
@@ -2343,6 +2343,7 @@ describe('api tests', () => {
|
||||
parent_microblock_hash: '0x',
|
||||
parent_microblock_sequence: 0,
|
||||
txs: ['0x4567000000000000000000000000000000000000000000000000000000000000'],
|
||||
microblock_tx_count: {},
|
||||
};
|
||||
|
||||
const searchResult1 = await supertest(api.server).get(
|
||||
@@ -7288,6 +7289,7 @@ describe('api tests', () => {
|
||||
execution_cost_runtime: 0,
|
||||
execution_cost_write_count: 0,
|
||||
execution_cost_write_length: 0,
|
||||
microblock_tx_count: {},
|
||||
};
|
||||
|
||||
expect(blockQuery.result).toEqual(expectedResp);
|
||||
@@ -7409,6 +7411,7 @@ describe('api tests', () => {
|
||||
parent_microblock_hash: '0x00',
|
||||
parent_microblock_sequence: 0,
|
||||
txs: ['0x0001'],
|
||||
microblock_tx_count: {},
|
||||
};
|
||||
const fetch1 = await supertest(api.server).get(
|
||||
`/extended/v1/block/by_height/${block1.block.block_height}`
|
||||
@@ -7455,7 +7458,11 @@ describe('api tests', () => {
|
||||
parent_microblock_sequence: microblock1.microblocks[0].microblock_sequence,
|
||||
// Ensure micro-orphaned tx `0x1002` is not included
|
||||
txs: ['0x0002', '0x1001'],
|
||||
microblock_tx_count: {
|
||||
'0xff01': microblock1.txs.length,
|
||||
},
|
||||
};
|
||||
|
||||
expect(fetch2.status).toBe(200);
|
||||
expect(fetch2.type).toBe('application/json');
|
||||
expect(JSON.parse(fetch2.text)).toEqual(expectedResp2);
|
||||
|
||||
@@ -173,6 +173,7 @@ describe('cache-control tests', () => {
|
||||
execution_cost_runtime: 0,
|
||||
execution_cost_write_count: 0,
|
||||
execution_cost_write_length: 0,
|
||||
microblock_tx_count: {},
|
||||
};
|
||||
|
||||
expect(blockQuery.result).toEqual(expectedResp1);
|
||||
@@ -316,6 +317,7 @@ describe('cache-control tests', () => {
|
||||
execution_cost_runtime: 0,
|
||||
execution_cost_write_count: 0,
|
||||
execution_cost_write_length: 0,
|
||||
microblock_tx_count: {},
|
||||
};
|
||||
|
||||
const fetchBlockByHash2 = await supertest(api.server).get(
|
||||
|
||||
Reference in New Issue
Block a user