Skip to content

Commit 13ac930

Browse files
authored
Merge pull request #1966 from hirosystems/develop
Cut beta v7.11.0-beta.5
2 parents 9a90c18 + d38b78a commit 13ac930

17 files changed

+376
-60
lines changed

.github/workflows/ci.yml

+36-12
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,9 @@ jobs:
158158
if: always()
159159

160160
- name: Upload coverage to Codecov
161-
uses: codecov/codecov-action@v3
161+
uses: codecov/codecov-action@v4
162+
with:
163+
token: ${{ secrets.CODECOV_TOKEN }}
162164
if: always()
163165

164166
- name: Upload coverage to Coveralls
@@ -214,7 +216,9 @@ jobs:
214216
if: always()
215217

216218
- name: Upload coverage to Codecov
217-
uses: codecov/codecov-action@v3
219+
uses: codecov/codecov-action@v4
220+
with:
221+
token: ${{ secrets.CODECOV_TOKEN }}
218222
if: always()
219223

220224
- name: Upload coverage to Coveralls
@@ -273,7 +277,9 @@ jobs:
273277
if: always()
274278

275279
- name: Upload coverage to Codecov
276-
uses: codecov/codecov-action@v3
280+
uses: codecov/codecov-action@v4
281+
with:
282+
token: ${{ secrets.CODECOV_TOKEN }}
277283
if: always()
278284

279285
- name: Upload coverage to Coveralls
@@ -332,7 +338,9 @@ jobs:
332338
if: always()
333339

334340
- name: Upload coverage to Codecov
335-
uses: codecov/codecov-action@v3
341+
uses: codecov/codecov-action@v4
342+
with:
343+
token: ${{ secrets.CODECOV_TOKEN }}
336344
if: always()
337345

338346
- name: Upload coverage to Coveralls
@@ -391,7 +399,9 @@ jobs:
391399
if: always()
392400

393401
- name: Upload coverage to Codecov
394-
uses: codecov/codecov-action@v3
402+
uses: codecov/codecov-action@v4
403+
with:
404+
token: ${{ secrets.CODECOV_TOKEN }}
395405
if: always()
396406

397407
- name: Upload coverage to Coveralls
@@ -450,7 +460,9 @@ jobs:
450460
if: always()
451461

452462
- name: Upload coverage to Codecov
453-
uses: codecov/codecov-action@v3
463+
uses: codecov/codecov-action@v4
464+
with:
465+
token: ${{ secrets.CODECOV_TOKEN }}
454466
if: always()
455467

456468
- name: Upload coverage to Coveralls
@@ -509,7 +521,9 @@ jobs:
509521
if: always()
510522

511523
- name: Upload coverage to Codecov
512-
uses: codecov/codecov-action@v3
524+
uses: codecov/codecov-action@v4
525+
with:
526+
token: ${{ secrets.CODECOV_TOKEN }}
513527
if: always()
514528

515529
- name: Upload coverage to Coveralls
@@ -586,7 +600,9 @@ jobs:
586600
if: always()
587601

588602
- name: Upload coverage to Codecov
589-
uses: codecov/codecov-action@v3
603+
uses: codecov/codecov-action@v4
604+
with:
605+
token: ${{ secrets.CODECOV_TOKEN }}
590606
if: always()
591607

592608
- name: Upload coverage to Coveralls
@@ -645,7 +661,9 @@ jobs:
645661
if: always()
646662

647663
- name: Upload coverage to Codecov
648-
uses: codecov/codecov-action@v3
664+
uses: codecov/codecov-action@v4
665+
with:
666+
token: ${{ secrets.CODECOV_TOKEN }}
649667
if: always()
650668

651669
- name: Upload coverage to Coveralls
@@ -704,7 +722,9 @@ jobs:
704722
if: always()
705723

706724
- name: Upload coverage to Codecov
707-
uses: codecov/codecov-action@v3
725+
uses: codecov/codecov-action@v4
726+
with:
727+
token: ${{ secrets.CODECOV_TOKEN }}
708728
if: always()
709729

710730
- name: Upload coverage to Coveralls
@@ -771,7 +791,9 @@ jobs:
771791
if: always()
772792

773793
- name: Upload coverage to Codecov
774-
uses: codecov/codecov-action@v3
794+
uses: codecov/codecov-action@v4
795+
with:
796+
token: ${{ secrets.CODECOV_TOKEN }}
775797
if: always()
776798

777799
- name: Upload coverage to Coveralls
@@ -838,7 +860,9 @@ jobs:
838860
if: always()
839861

840862
- name: Upload coverage to Codecov
841-
uses: codecov/codecov-action@v3
863+
uses: codecov/codecov-action@v4
864+
with:
865+
token: ${{ secrets.CODECOV_TOKEN }}
842866
if: always()
843867

844868
- name: Upload coverage to Coveralls
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"last_1h": 846.75,
3+
"last_24h": 635.2,
4+
"last_7d": 731.26,
5+
"last_30d": 738.67
6+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"type": "object",
3+
"title": "AverageBlockTimesResponse",
4+
"description": "Request to fetch average block times (in seconds)",
5+
"additionalProperties": false,
6+
"required": [
7+
"last_1h",
8+
"last_24h",
9+
"last_7d",
10+
"last_30d"
11+
],
12+
"properties": {
13+
"last_1h": {
14+
"type": "number",
15+
"description": "Average block times over the last hour (in seconds)"
16+
},
17+
"last_24h": {
18+
"type": "number",
19+
"description": "Average block times over the last 24 hours (in seconds)"
20+
},
21+
"last_7d": {
22+
"type": "number",
23+
"description": "Average block times over the last 7 days (in seconds)"
24+
},
25+
"last_30d": {
26+
"type": "number",
27+
"description": "Average block times over the last 30 days (in seconds)"
28+
}
29+
}
30+
}

docs/api/blocks/get-burn-blocks.example.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313
"0xdaf61d2b355f35c94cf019af99aeb73d8e7db7301c7cd693a464ebd1cfc2228c",
1414
"0xb9e9b308cf9621ecbf66ca7b4689fe384b9b67c4588ec827d8163ab602fb935e",
1515
"0x754562cba6ec243f90485e97778ab472f462fd123ef5b83cc79d8759ca8875f5"
16-
]
16+
],
17+
"avg_block_time": 15.3,
18+
"total_tx_count": 728
1719
}
1820
]
1921
}

docs/entities/blocks/burn-block.example.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,7 @@
88
"0xdaf61d2b355f35c94cf019af99aeb73d8e7db7301c7cd693a464ebd1cfc2228c",
99
"0xb9e9b308cf9621ecbf66ca7b4689fe384b9b67c4588ec827d8163ab602fb935e",
1010
"0x754562cba6ec243f90485e97778ab472f462fd123ef5b83cc79d8759ca8875f5"
11-
]
11+
],
12+
"avg_block_time": 15.3,
13+
"total_tx_count": 728
1214
}

docs/entities/blocks/burn-block.schema.json

+11-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
"burn_block_time_iso",
99
"burn_block_hash",
1010
"burn_block_height",
11-
"stacks_blocks"
11+
"stacks_blocks",
12+
"avg_block_time",
13+
"total_tx_count"
1214
],
1315
"properties": {
1416
"burn_block_time": {
@@ -33,6 +35,14 @@
3335
"type": "string"
3436
},
3537
"description": "Hashes of the Stacks blocks included in the burn block"
38+
},
39+
"avg_block_time": {
40+
"type": "number",
41+
"description": "Average time between blocks in seconds. Returns 0 if there is only one block in the burn block."
42+
},
43+
"total_tx_count": {
44+
"type": "integer",
45+
"description": "Total number of transactions in the Stacks blocks associated with this burn block"
3646
}
3747
}
3848
}

docs/generated.d.ts

+30
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export type SchemaMergeRootStub =
1313
| AddressTransactionsWithTransfersListResponse
1414
| AddressTransactionsListResponse
1515
| AddressTransactionsV2ListResponse
16+
| AverageBlockTimesResponse
1617
| BlockListResponse
1718
| BurnBlockListResponse
1819
| NakamotoBlockListResponse
@@ -1285,6 +1286,27 @@ export interface AddressTransaction {
12851286
[k: string]: unknown | undefined;
12861287
};
12871288
}
1289+
/**
1290+
* Request to fetch average block times (in seconds)
1291+
*/
1292+
export interface AverageBlockTimesResponse {
1293+
/**
1294+
* Average block times over the last hour (in seconds)
1295+
*/
1296+
last_1h: number;
1297+
/**
1298+
* Average block times over the last 24 hours (in seconds)
1299+
*/
1300+
last_24h: number;
1301+
/**
1302+
* Average block times over the last 7 days (in seconds)
1303+
*/
1304+
last_7d: number;
1305+
/**
1306+
* Average block times over the last 30 days (in seconds)
1307+
*/
1308+
last_30d: number;
1309+
}
12881310
/**
12891311
* GET request that returns blocks
12901312
*/
@@ -1444,6 +1466,14 @@ export interface BurnBlock {
14441466
* Hashes of the Stacks blocks included in the burn block
14451467
*/
14461468
stacks_blocks: string[];
1469+
/**
1470+
* Average time between blocks in seconds. Returns 0 if there is only one block in the burn block.
1471+
*/
1472+
avg_block_time: number;
1473+
/**
1474+
* Total number of transactions in the Stacks blocks associated with this burn block
1475+
*/
1476+
total_tx_count: number;
14471477
}
14481478
/**
14491479
* GET request that returns blocks

docs/openapi.yaml

+19-1
Original file line numberDiff line numberDiff line change
@@ -779,7 +779,25 @@ paths:
779779
$ref: ./api/blocks/get-nakamoto-blocks.schema.json
780780
example:
781781
$ref: ./api/blocks/get-nakamoto-blocks.example.json
782-
782+
783+
/extended/v2/blocks/average-times:
784+
get:
785+
summary: Get average block times
786+
description: |
787+
Retrieves average block times (in seconds)
788+
tags:
789+
- Blocks
790+
operationId: get_average_block_times
791+
responses:
792+
200:
793+
description: Average block times (in seconds)
794+
content:
795+
application/json:
796+
schema:
797+
$ref: ./api/blocks/get-average-times.schema.json
798+
example:
799+
$ref: ./api/blocks/get-average-times.example.json
800+
783801
/extended/v2/blocks/{height_or_hash}:
784802
get:
785803
summary: Get block

src/api/routes/v2/blocks.ts

+17
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,23 @@ export function createV2BlocksRouter(db: PgStore): express.Router {
4343
})
4444
);
4545

46+
router.get(
47+
'/average-times',
48+
cacheHandler,
49+
asyncHandler(async (_req, res) => {
50+
const query = await db.v2.getAverageBlockTimes();
51+
// Round to 2 decimal places
52+
const times = {
53+
last_1h: parseFloat(query.last_1h.toFixed(2)),
54+
last_24h: parseFloat(query.last_24h.toFixed(2)),
55+
last_7d: parseFloat(query.last_7d.toFixed(2)),
56+
last_30d: parseFloat(query.last_30d.toFixed(2)),
57+
};
58+
setETagCacheHeaders(res);
59+
res.json(times);
60+
})
61+
);
62+
4663
router.get(
4764
'/:height_or_hash',
4865
cacheHandler,

src/api/routes/v2/burn-blocks.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as express from 'express';
22
import {
33
BurnBlockListResponse,
4+
BurnBlock,
45
NakamotoBlockListResponse,
56
} from '@stacks/stacks-blockchain-api-types';
67
import { getETagCacheHandler, setETagCacheHeaders } from '../../controllers/cache-controller';
@@ -52,8 +53,9 @@ export function createV2BurnBlocksRouter(db: PgStore): express.Router {
5253
res.status(404).json({ errors: 'Not found' });
5354
return;
5455
}
56+
const response: BurnBlock = parseDbBurnBlock(block);
5557
setETagCacheHeaders(res);
56-
res.json(parseDbBurnBlock(block));
58+
res.json(response);
5759
})
5860
);
5961

src/api/routes/v2/helpers.ts

+2
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ export function parseDbBurnBlock(block: DbBurnBlock): BurnBlock {
6060
burn_block_hash: block.burn_block_hash,
6161
burn_block_height: block.burn_block_height,
6262
stacks_blocks: block.stacks_blocks,
63+
avg_block_time: parseFloat(parseFloat(block.avg_block_time ?? '0').toFixed(2)),
64+
total_tx_count: parseInt(block.total_tx_count),
6365
};
6466
return burnBlock;
6567
}

src/datastore/common.ts

+3
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ export interface DbBurnBlock {
5555
burn_block_hash: string;
5656
burn_block_height: number;
5757
stacks_blocks: string[];
58+
avg_block_time: string | null;
59+
total_tx_count: string;
5860
}
5961

6062
export interface DbBurnchainReward {
@@ -1257,6 +1259,7 @@ export interface BlockInsertValues {
12571259
parent_microblock_hash: PgBytea;
12581260
parent_microblock_sequence: number;
12591261
block_height: number;
1262+
block_time: number;
12601263
burn_block_time: number;
12611264
burn_block_hash: PgBytea;
12621265
burn_block_height: number;

0 commit comments

Comments
 (0)