Skip to content

Commit 32f879f

Browse files
authored
Merge branch 'master' into develop
2 parents 2bfacf6 + 3ffcc11 commit 32f879f

File tree

8 files changed

+134
-49
lines changed

8 files changed

+134
-49
lines changed

CHANGELOG.md

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,53 @@
1+
## [8.13.1](https://github.com/hirosystems/stacks-blockchain-api/compare/v8.13.0...v8.13.1) (2025-09-23)
2+
3+
4+
### Bug Fixes
5+
6+
* **notifier:** include block times in redis updates ([#2352](https://github.com/hirosystems/stacks-blockchain-api/issues/2352)) ([d4324b8](https://github.com/hirosystems/stacks-blockchain-api/commit/d4324b8df0e8d6a2b3704540e2c88c132666b272))
7+
8+
## [8.13.0](https://github.com/hirosystems/stacks-blockchain-api/compare/v8.12.1...v8.13.0) (2025-09-09)
9+
10+
11+
### Features
12+
13+
* add redis index notifier ([#2321](https://github.com/hirosystems/stacks-blockchain-api/issues/2321)) ([5c49f49](https://github.com/hirosystems/stacks-blockchain-api/commit/5c49f49fb6f3c56c92ccd4be63e301d2b495a550))
14+
15+
## [8.12.1](https://github.com/hirosystems/stacks-blockchain-api/compare/v8.12.0...v8.12.1) (2025-08-26)
16+
17+
18+
### Bug Fixes
19+
20+
* include nakamoto coinbase txs on coinbase txs filter ([#2339](https://github.com/hirosystems/stacks-blockchain-api/issues/2339)) ([c9ef5e8](https://github.com/hirosystems/stacks-blockchain-api/commit/c9ef5e810776f11ca30e71846ebe297e0adbb1e6))
21+
* pox cycle signer stackers query pagination ([#2345](https://github.com/hirosystems/stacks-blockchain-api/issues/2345)) ([1353554](https://github.com/hirosystems/stacks-blockchain-api/commit/1353554c11e6f51bf8a8676bb8f9e35ae670ffbc))
22+
23+
## [8.12.0](https://github.com/hirosystems/stacks-blockchain-api/compare/v8.11.6...v8.12.0) (2025-08-06)
24+
25+
26+
### Features
27+
28+
* Add exclude_function_args parameter to reduce transaction response sizes ([#2312](https://github.com/hirosystems/stacks-blockchain-api/issues/2312)) ([852a60e](https://github.com/hirosystems/stacks-blockchain-api/commit/852a60e96080c82c95b8942d6828a72c778f7d87))
29+
* add replaced_by_tx_id to replaced mempool transactions ([#2271](https://github.com/hirosystems/stacks-blockchain-api/issues/2271)) ([a70c3d1](https://github.com/hirosystems/stacks-blockchain-api/commit/a70c3d176091a66ede2e21f6941d5e4c416ae2a3))
30+
* **prometheus:** add chain tip metrics ([#2333](https://github.com/hirosystems/stacks-blockchain-api/issues/2333)) ([bde1037](https://github.com/hirosystems/stacks-blockchain-api/commit/bde1037edf88452e20ed707cfd138876c68ea8a3))
31+
* SNP integration ([#2291](https://github.com/hirosystems/stacks-blockchain-api/issues/2291)) ([9a159e1](https://github.com/hirosystems/stacks-blockchain-api/commit/9a159e14dacfac40544ad9ded76c2136e419ed0b))
32+
33+
34+
### Bug Fixes
35+
36+
* drop redundant db indexes ([#2329](https://github.com/hirosystems/stacks-blockchain-api/issues/2329)) ([0ddd6a6](https://github.com/hirosystems/stacks-blockchain-api/commit/0ddd6a613219671533a5f3d9c33ead501d7fc3f8))
37+
* ensure some ops only run when SNP is not enabled ([fd4717b](https://github.com/hirosystems/stacks-blockchain-api/commit/fd4717be91ecd89328d15b2fea29b5297ca76a33))
38+
* only ingest snp chain events to avoid db bloat ([287f572](https://github.com/hirosystems/stacks-blockchain-api/commit/287f572c49fa8405a907a5023aa815157f6162ca))
39+
* optimize queries to prune and restore mempool rbf txs ([#2327](https://github.com/hirosystems/stacks-blockchain-api/issues/2327)) ([0b196f0](https://github.com/hirosystems/stacks-blockchain-api/commit/0b196f0b81b3e4661e092e372df476ab13f284b8))
40+
* optimize replace-by-fee mempool calculations ([#2326](https://github.com/hirosystems/stacks-blockchain-api/issues/2326)) ([01998bc](https://github.com/hirosystems/stacks-blockchain-api/commit/01998bcecf337200ee9582cb45682f9966977432))
41+
* parallelize mempool rbf updates ([#2328](https://github.com/hirosystems/stacks-blockchain-api/issues/2328)) ([e7347e5](https://github.com/hirosystems/stacks-blockchain-api/commit/e7347e525f938d67cd77253b8efcc8ec33c923d4))
42+
* update snp image in tests ([c7c0dbb](https://github.com/hirosystems/stacks-blockchain-api/commit/c7c0dbbac6d2f5736fbca338798da23fb16e3ada))
43+
44+
## [8.11.6](https://github.com/hirosystems/stacks-blockchain-api/compare/v8.11.5...v8.11.6) (2025-07-30)
45+
46+
47+
### Bug Fixes
48+
49+
* update stx year 2050 supply to reflect sip-031 increase ([#2334](https://github.com/hirosystems/stacks-blockchain-api/issues/2334)) ([6916796](https://github.com/hirosystems/stacks-blockchain-api/commit/6916796f3f11dcc182460367ade104cbda480d46))
50+
151
## [8.11.5](https://github.com/hirosystems/stacks-blockchain-api/compare/v8.11.4...v8.11.5) (2025-07-18)
252

353

src/datastore/common.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1110,8 +1110,14 @@ export interface DbPoxCycleSignerStacker {
11101110
stacker_type: 'solo' | 'pooled';
11111111
}
11121112

1113+
export interface BlockHeader {
1114+
index_block_hash: string;
1115+
block_height: number;
1116+
block_time: number;
1117+
}
1118+
11131119
interface ReOrgEntities {
1114-
blockHeaders: { index_block_hash: string; block_height: number }[];
1120+
blockHeaders: BlockHeader[];
11151121
blocks: number;
11161122
microblockHashes: string[];
11171123
microblocks: number;

src/datastore/pg-write-store.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,14 @@ export class PgWriteStore extends PgStore {
414414
}
415415
});
416416
if (isCanonical) {
417-
await this.redisNotifier?.notify(reorg, data.block.index_block_hash, data.block.block_height);
417+
await this.redisNotifier?.notify(
418+
{
419+
index_block_hash: data.block.index_block_hash,
420+
block_height: data.block.block_height,
421+
block_time: data.block.block_time,
422+
},
423+
reorg
424+
);
418425
}
419426
// Do we have an IBD height defined in ENV? If so, check if this block update reached it.
420427
const ibdHeight = getIbdBlockHeight();
@@ -3573,6 +3580,7 @@ export class PgWriteStore extends PgStore {
35733580
updatedEntities.markedCanonical.blockHeaders.unshift({
35743581
index_block_hash: restoredBlockResult[0].index_block_hash,
35753582
block_height: restoredBlockResult[0].block_height,
3583+
block_time: restoredBlockResult[0].block_time,
35763584
});
35773585

35783586
// Orphan the now conflicting block at the same height
@@ -3620,6 +3628,7 @@ export class PgWriteStore extends PgStore {
36203628
updatedEntities.markedNonCanonical.blockHeaders.unshift({
36213629
index_block_hash: orphanedBlockResult[0].index_block_hash,
36223630
block_height: orphanedBlockResult[0].block_height,
3631+
block_time: orphanedBlockResult[0].block_time,
36233632
});
36243633
const markNonCanonicalResult = await this.markEntitiesCanonical(
36253634
sql,

src/datastore/redis-notifier.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import Redis, { Cluster, RedisOptions } from 'ioredis';
2-
import { ReOrgUpdatedEntities } from './common';
2+
import { BlockHeader, ReOrgUpdatedEntities } from './common';
33
import { ChainID } from '@stacks/transactions';
44
import { getApiConfiguredChainID } from '../helpers';
55
import { logger } from '@hirosystems/api-toolkit';
@@ -24,32 +24,36 @@ export class RedisNotifier {
2424
/**
2525
* Broadcast index progress message to the Redis queue.
2626
* @param reOrg - The re-org updated entities, if any
27-
* @param indexBlockHash - Block hash of the newest canonical block
28-
* @param blockHeight - Block height of the newest canonical block
27+
* @param block - The newest canonical block
2928
*/
30-
async notify(reOrg: ReOrgUpdatedEntities, indexBlockHash: string, blockHeight: number) {
29+
async notify(block: BlockHeader, reOrg: ReOrgUpdatedEntities) {
30+
const time = Date.now();
3131
const message = {
32-
id: `stacks-${blockHeight}-${indexBlockHash}-${Date.now()}`,
32+
id: `stacks-${block.block_height}-${block.index_block_hash}-${time}`,
3333
payload: {
3434
chain: 'stacks',
3535
network: this.chainId === ChainID.Mainnet ? 'mainnet' : 'testnet',
36+
time,
3637
apply_blocks: [
3738
...reOrg.markedCanonical.blockHeaders.map(block => ({
3839
hash: block.index_block_hash,
3940
index: block.block_height,
41+
time: block.block_time,
4042
})),
4143
{
42-
hash: indexBlockHash,
43-
index: blockHeight,
44+
hash: block.index_block_hash,
45+
index: block.block_height,
46+
time: block.block_time,
4447
},
4548
],
4649
rollback_blocks: reOrg.markedNonCanonical.blockHeaders.map(block => ({
4750
hash: block.index_block_hash,
4851
index: block.block_height,
52+
time: block.block_time,
4953
})),
5054
},
5155
};
52-
logger.debug(message, 'RedisNotifier broadcasting index progress message');
56+
logger.info(message, 'RedisNotifier broadcasting index progress message');
5357
await this.redis.xadd(this.queue, '*', 'data', JSON.stringify(message));
5458
}
5559

src/helpers.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,8 +168,11 @@ export function formatMapToObject<TKey extends string, TValue, TFormatted>(
168168
// > Block reward: 1000 STX/block for first 4 yrs;
169169
// > 500 STX/block for following 4 yrs;
170170
// > 250 for the 4 yrs after that; and then 125 STX/block in perpetuity after that.
171-
// We are going to use the year 2050 projected supply because "125 STX/block in perpetuity" means the total supply is infinite.
172-
export const TOTAL_STACKS_YEAR_2050 = new BigNumber(1_818_000_000n.toString());
171+
// We are going to use the year 2050 projected supply because "125 STX/block in perpetuity" means
172+
// the total supply is infinite.
173+
// After SIP-031 was activated with Stacks 3.2, however, the total supply was increased by 500M STX
174+
// to 2.318B STX.
175+
export const TOTAL_STACKS_YEAR_2050 = new BigNumber(2_318_000_000n.toString());
173176

174177
const MICROSTACKS_IN_STACKS = 1_000_000n;
175178
export const STACKS_DECIMAL_PLACES = 6;

tests/api/datastore.test.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3834,10 +3834,10 @@ describe('postgres datastore', () => {
38343834
const expectedReorgResult: ReOrgUpdatedEntities = {
38353835
markedCanonical: {
38363836
blockHeaders: [
3837-
{ block_height: 1, index_block_hash: '0xaa' },
3838-
{ block_height: 2, index_block_hash: '0xbb' },
3839-
{ block_height: 3, index_block_hash: '0xcc' },
3840-
{ block_height: 4, index_block_hash: '0xdd' },
3837+
{ block_height: 1, index_block_hash: '0xaa', block_time: 1234 },
3838+
{ block_height: 2, index_block_hash: '0xbb', block_time: 1234 },
3839+
{ block_height: 3, index_block_hash: '0xcc', block_time: 1234 },
3840+
{ block_height: 4, index_block_hash: '0xdd', block_time: 1234 },
38413841
],
38423842
blocks: 4,
38433843
microblocks: 0,
@@ -3860,7 +3860,7 @@ describe('postgres datastore', () => {
38603860
poxSigners: 0,
38613861
},
38623862
markedNonCanonical: {
3863-
blockHeaders: [{ block_height: 3, index_block_hash: '0xccbb' }],
3863+
blockHeaders: [{ block_height: 3, index_block_hash: '0xccbb', block_time: 1234 }],
38643864
blocks: 1,
38653865
microblocks: 0,
38663866
microblockHashes: [],

tests/api/other.test.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ describe('other tests', () => {
147147
const expectedResp1 = {
148148
unlocked_percent: '100.00',
149149
total_stx: '235000000.000000',
150-
total_stx_year_2050: '1818000000.000000',
150+
total_stx_year_2050: '2318000000.000000',
151151
unlocked_stx: '235000000.000000',
152152
block_height: 1,
153153
};
@@ -175,7 +175,7 @@ describe('other tests', () => {
175175
unlocked_percent: '100.00',
176176
total_stx: microStxToStx(expectedTotalStx2),
177177
unlocked_stx: microStxToStx(expectedTotalStx2),
178-
total_stx_year_2050: '1818000000.000000',
178+
total_stx_year_2050: '2318000000.000000',
179179
block_height: dbBlock1.block_height,
180180
};
181181
expect(JSON.parse(result2.text)).toEqual(expectedResp2);
@@ -206,7 +206,7 @@ describe('other tests', () => {
206206
const expectedResp3 = {
207207
unlocked_percent: '100.00',
208208
total_stx: microStxToStx(expectedTotalStx3),
209-
total_stx_year_2050: '1818000000.000000',
209+
total_stx_year_2050: '2318000000.000000',
210210
unlocked_stx: microStxToStx(expectedTotalStx3),
211211
block_height: dbBlock1.block_height,
212212
};
@@ -236,8 +236,8 @@ describe('other tests', () => {
236236
unlockedSupplyFormatted: new Intl.NumberFormat('en', {
237237
minimumFractionDigits: STACKS_DECIMAL_PLACES,
238238
}).format(parseInt(microStxToStx(expectedTotalStx3))),
239-
totalStacksYear2050: '1818000000.000000',
240-
totalStacksYear2050Formatted: '1,818,000,000.000000',
239+
totalStacksYear2050: '2318000000.000000',
240+
totalStacksYear2050Formatted: '2,318,000,000.000000',
241241
blockHeight: dbBlock1.block_height.toString(),
242242
};
243243
expect(JSON.parse(result6.text)).toEqual(expectedResp6);

tests/api/redis-notifier.test.ts

Lines changed: 40 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -44,16 +44,19 @@ describe('redis notifier', () => {
4444
block_height: 1,
4545
block_hash: '0x1234',
4646
index_block_hash: '0x1234',
47+
block_time: 1234,
4748
}).build();
4849
await db.update(block1);
4950

5051
expect(messages.length).toBe(1);
51-
expect(JSON.parse(messages[0]).payload).toEqual({
52-
chain: 'stacks',
53-
network: 'mainnet',
54-
apply_blocks: [{ hash: '0x1234', index: 1 }],
55-
rollback_blocks: [],
56-
});
52+
expect(JSON.parse(messages[0]).payload).toEqual(
53+
expect.objectContaining({
54+
chain: 'stacks',
55+
network: 'mainnet',
56+
apply_blocks: [{ hash: '0x1234', index: 1, time: 1234 }],
57+
rollback_blocks: [],
58+
})
59+
);
5760
});
5861

5962
test('updates redis with re-orgs', async () => {
@@ -62,31 +65,37 @@ describe('redis notifier', () => {
6265
block_height: 1,
6366
block_hash: '0x1234',
6467
index_block_hash: '0x1234',
68+
block_time: 1234,
6569
}).build()
6670
);
6771
expect(messages.length).toBe(1);
68-
expect(JSON.parse(messages[0]).payload).toEqual({
69-
chain: 'stacks',
70-
network: 'mainnet',
71-
apply_blocks: [{ hash: '0x1234', index: 1 }],
72-
rollback_blocks: [],
73-
});
72+
expect(JSON.parse(messages[0]).payload).toEqual(
73+
expect.objectContaining({
74+
chain: 'stacks',
75+
network: 'mainnet',
76+
apply_blocks: [{ hash: '0x1234', index: 1, time: 1234 }],
77+
rollback_blocks: [],
78+
})
79+
);
7480

7581
await db.update(
7682
new TestBlockBuilder({
7783
block_height: 2,
7884
block_hash: '0x1235',
7985
index_block_hash: '0x1235',
8086
parent_index_block_hash: '0x1234',
87+
block_time: 1234,
8188
}).build()
8289
);
8390
expect(messages.length).toBe(2);
84-
expect(JSON.parse(messages[1]).payload).toEqual({
85-
chain: 'stacks',
86-
network: 'mainnet',
87-
apply_blocks: [{ hash: '0x1235', index: 2 }],
88-
rollback_blocks: [],
89-
});
91+
expect(JSON.parse(messages[1]).payload).toEqual(
92+
expect.objectContaining({
93+
chain: 'stacks',
94+
network: 'mainnet',
95+
apply_blocks: [{ hash: '0x1235', index: 2, time: 1234 }],
96+
rollback_blocks: [],
97+
})
98+
);
9099

91100
// Re-org block 2, should not send a message because this block is not canonical
92101
await db.update(
@@ -95,6 +104,7 @@ describe('redis notifier', () => {
95104
block_hash: '0x1235aa',
96105
index_block_hash: '0x1235aa',
97106
parent_index_block_hash: '0x1234',
107+
block_time: 1234,
98108
}).build()
99109
);
100110
expect(messages.length).toBe(2);
@@ -106,17 +116,20 @@ describe('redis notifier', () => {
106116
block_hash: '0x1236',
107117
index_block_hash: '0x1236',
108118
parent_index_block_hash: '0x1235aa',
119+
block_time: 1234,
109120
}).build()
110121
);
111122
expect(messages.length).toBe(3);
112-
expect(JSON.parse(messages[2]).payload).toEqual({
113-
chain: 'stacks',
114-
network: 'mainnet',
115-
apply_blocks: [
116-
{ hash: '0x1235aa', index: 2 },
117-
{ hash: '0x1236', index: 3 },
118-
],
119-
rollback_blocks: [{ hash: '0x1235', index: 2 }],
120-
});
123+
expect(JSON.parse(messages[2]).payload).toEqual(
124+
expect.objectContaining({
125+
chain: 'stacks',
126+
network: 'mainnet',
127+
apply_blocks: [
128+
{ hash: '0x1235aa', index: 2, time: 1234 },
129+
{ hash: '0x1236', index: 3, time: 1234 },
130+
],
131+
rollback_blocks: [{ hash: '0x1235', index: 2, time: 1234 }],
132+
})
133+
);
121134
});
122135
});

0 commit comments

Comments
 (0)