Skip to content

Commit 285806f

Browse files
authored
feat: pox-4 support (#1754)
* feat: handle pox-3 force unlocks * chore: todo note * feat: handle pox-3 force unlocks, pox-4 events, and revoke-delegate-stx event * chore: rename pox-2 file * chore: simplified pox route paths * feat: add migration to create pox4_events table * test: follow redirects in test fetch helper * chore: fix storing different pox version events * test: fix tests with missing pox4_events * chore: move delegations lookup endpoint into pox router * fix: handle pox4_events during reorgs * test: fix pox4events reorg count * chore: update stacks-node image to stacks 3.0 * test: begin transitioning pox tests to use pox-4 * chore: bump stacks-node to wip nakamoto branch * test: switch more tests from pox-3 to pox-4 * fix: tx fee fall back in faucet * test: update delegation check endpoints * chore: isolate error in delegate-revoke test * chore: pox3 to pox4 misc renames * ci: rename 2.4 to 2.5 * test: remove no-longer applicable delegate-stx while stacking test * chore: remove incorrect commend in pox4 test
1 parent cb38b68 commit 285806f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+1272
-935
lines changed

.github/workflows/ci.yml

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -520,24 +520,24 @@ jobs:
520520
flag-name: run-${{ github.job }}
521521
parallel: true
522522

523-
test-2_4:
523+
test-2_5:
524524
strategy:
525525
fail-fast: false
526526
matrix:
527527
suite:
528528
[
529529
block-zero-handling,
530530
faucet-stx,
531-
pox-3-btc-address-formats,
532-
pox-3-delegate-aggregation,
533-
pox-3-delegate-stacking,
534-
pox-3-delegate-revoked-stacking,
535-
pox-3-stack-extend-increase,
536-
pox-3-rosetta-btc-addr-types,
537-
pox-3-rosetta-cycle-phases,
538-
pox-3-rosetta-segwit,
539-
pox-3-burnchain-stack-stx,
540-
pox-3-burnchain-delegate-stx,
531+
pox-4-btc-address-formats,
532+
pox-4-delegate-aggregation,
533+
pox-4-delegate-stacking,
534+
pox-4-delegate-revoked-stacking,
535+
pox-4-stack-extend-increase,
536+
pox-4-rosetta-btc-addr-types,
537+
pox-4-rosetta-cycle-phases,
538+
pox-4-rosetta-segwit,
539+
pox-4-burnchain-stack-stx,
540+
pox-4-burnchain-delegate-stx,
541541
]
542542
runs-on: ubuntu-latest
543543
steps:
@@ -575,7 +575,7 @@ jobs:
575575
npm run devenv:logs-krypton -- --no-color &> docker-compose-logs.txt &
576576
577577
- name: Run tests
578-
run: npm run test:2.4 -- --testPathPattern "${{ matrix.suite }}"
578+
run: npm run test:2.5 -- --testPathPattern "${{ matrix.suite }}"
579579

580580
- name: Print integration environment logs
581581
run: cat docker-compose-logs.txt
@@ -855,7 +855,7 @@ jobs:
855855
- lint
856856
- lint-docs
857857
- test
858-
- test-2_4
858+
- test-2_5
859859
- test-bns
860860
- test-rosetta
861861
- test-rosetta-cli-construction

.vscode/launch.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -316,14 +316,14 @@
316316
{
317317
"type": "node",
318318
"request": "launch",
319-
"name": "Jest: 2.4",
319+
"name": "Jest: 2.5",
320320
"program": "${workspaceFolder}/node_modules/.bin/jest",
321321
"args": [
322322
"--testTimeout=3600000",
323323
"--runInBand",
324324
"--no-cache",
325325
"--config",
326-
"${workspaceRoot}/tests/jest.config.2.4.js"
326+
"${workspaceRoot}/tests/jest.config.2.5.js",
327327
],
328328
"outputCapture": "std",
329329
"console": "integratedTerminal",

docker/docker-compose.dev.stacks-blockchain.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
version: '3.7'
22
services:
33
stacks-blockchain:
4-
image: "hirosystems/stacks-api-e2e:stacks2.4-f930deb"
4+
image: "hirosystems/stacks-api-e2e:stacks3.0-800259e"
55
restart: on-failure
66
environment:
77
STACKS_EVENT_OBSERVER: host.docker.internal:3700

docker/docker-compose.dev.stacks-krypton.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
version: '3.7'
22
services:
33
stacks-blockchain:
4-
image: "hirosystems/stacks-api-e2e:stacks2.4-f930deb"
4+
image: "hirosystems/stacks-api-e2e:stacks3.0-800259e"
55
ports:
66
- "18443:18443" # bitcoin regtest JSON-RPC interface
77
- "18444:18444" # bitcoin regtest p2p

docs/api/info/get-status.schema.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@
2323
"type": "integer",
2424
"nullable": true
2525
},
26+
"pox_v3_unlock_height": {
27+
"type": "integer",
28+
"nullable": true
29+
},
2630
"chain_tip": {
2731
"$ref": "../../entities/info/chain-tip.schema.json"
2832
}

docs/generated.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1714,6 +1714,7 @@ export interface ServerStatusResponse {
17141714
status: string;
17151715
pox_v1_unlock_height?: number;
17161716
pox_v2_unlock_height?: number;
1717+
pox_v3_unlock_height?: number;
17171718
chain_tip?: ChainTip;
17181719
}
17191720
/**

migrations/1701368149776_nakamoto-txs.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
/** @param { import("node-pg-migrate").MigrationBuilder } pgm */
22
exports.up = pgm => {
3+
pgm.addColumn('pox_state', {
4+
pox_v3_unlock_height: {
5+
type: 'bigint',
6+
notNull: true,
7+
default: 0,
8+
},
9+
});
10+
311
pgm.addColumns('txs', {
412
// `nakamoto-coinbase` tx types
513
coinbase_vrf_proof: 'bytea',
Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
/** @param { import("node-pg-migrate").MigrationBuilder } pgm */
2+
exports.up = pgm => {
3+
// Adds pox4_events table which matches previous pox2_events table
4+
pgm.createTable('pox4_events', {
5+
id: {
6+
type: 'bigserial',
7+
primaryKey: true,
8+
},
9+
event_index: {
10+
type: 'integer',
11+
notNull: true,
12+
},
13+
tx_id: {
14+
notNull: true,
15+
type: 'bytea',
16+
},
17+
tx_index: {
18+
type: 'smallint',
19+
notNull: true,
20+
},
21+
block_height: {
22+
type: 'integer',
23+
notNull: true,
24+
},
25+
index_block_hash: {
26+
type: 'bytea',
27+
notNull: true,
28+
},
29+
parent_index_block_hash: {
30+
type: 'bytea',
31+
notNull: true,
32+
},
33+
microblock_hash: {
34+
type: 'bytea',
35+
notNull: true,
36+
},
37+
microblock_sequence: {
38+
type: 'integer',
39+
notNull: true,
40+
},
41+
microblock_canonical: {
42+
type: 'boolean',
43+
notNull: true,
44+
},
45+
canonical: {
46+
type: 'boolean',
47+
notNull: true,
48+
},
49+
stacker: {
50+
type: 'string',
51+
notNull: true,
52+
},
53+
locked: {
54+
type: 'numeric',
55+
notNull: true,
56+
},
57+
balance: {
58+
type: 'numeric',
59+
notNull: true,
60+
},
61+
burnchain_unlock_height: {
62+
type: 'bigint',
63+
notNull: true,
64+
},
65+
name: {
66+
type: 'string',
67+
notNull: true,
68+
},
69+
pox_addr: {
70+
type: 'string',
71+
},
72+
pox_addr_raw: {
73+
type: 'bytea',
74+
},
75+
first_cycle_locked: {
76+
// unique to handle-unlock
77+
type: 'numeric',
78+
},
79+
first_unlocked_cycle: {
80+
// unique to handle-unlock
81+
type: 'numeric',
82+
},
83+
delegate_to: {
84+
// unique to delegate-stx
85+
type: 'string',
86+
},
87+
lock_period: {
88+
// unique to stack-stx, delegate-stack-stx
89+
type: 'numeric',
90+
},
91+
lock_amount: {
92+
// unique to stack-stx, delegate-stack-stx
93+
type: 'numeric',
94+
},
95+
start_burn_height: {
96+
// unique to stack-stx, delegate-stack-stx
97+
type: 'numeric',
98+
},
99+
unlock_burn_height: {
100+
// unique to stack-stx, stack-extend, delegate-stack-stx, delegate-stack-extend, delegate-stx
101+
type: 'numeric',
102+
},
103+
delegator: {
104+
// unique to delegate-stack-stx, delegate-stack-increase, delegate-stack-extend
105+
type: 'string',
106+
},
107+
increase_by: {
108+
// unique to stack-increase, delegate-stack-increase
109+
type: 'numeric',
110+
},
111+
total_locked: {
112+
// unique to stack-increase, delegate-stack-increase
113+
type: 'numeric',
114+
},
115+
extend_count: {
116+
// unique to stack-extend, delegate-stack-extend
117+
type: 'numeric',
118+
},
119+
reward_cycle: {
120+
// unique to stack-aggregation-*
121+
type: 'numeric',
122+
},
123+
amount_ustx: {
124+
// unique to stack-aggregation-*, delegate-stx
125+
type: 'numeric',
126+
},
127+
});
128+
129+
pgm.addConstraint(
130+
'pox4_events',
131+
'valid_event_specific_columns',
132+
`CHECK (
133+
CASE name
134+
WHEN 'handle-unlock' THEN
135+
first_cycle_locked IS NOT NULL AND
136+
first_unlocked_cycle IS NOT NULL
137+
WHEN 'stack-stx' THEN
138+
lock_period IS NOT NULL AND
139+
lock_amount IS NOT NULL AND
140+
start_burn_height IS NOT NULL AND
141+
unlock_burn_height IS NOT NULL
142+
WHEN 'stack-increase' THEN
143+
increase_by IS NOT NULL AND
144+
total_locked IS NOT NULL
145+
WHEN 'stack-extend' THEN
146+
extend_count IS NOT NULL AND
147+
unlock_burn_height IS NOT NULL
148+
WHEN 'delegate-stx' THEN
149+
amount_ustx IS NOT NULL AND
150+
delegate_to IS NOT NULL
151+
WHEN 'delegate-stack-stx' THEN
152+
lock_period IS NOT NULL AND
153+
lock_amount IS NOT NULL AND
154+
start_burn_height IS NOT NULL AND
155+
unlock_burn_height IS NOT NULL AND
156+
delegator IS NOT NULL
157+
WHEN 'delegate-stack-increase' THEN
158+
increase_by IS NOT NULL AND
159+
total_locked IS NOT NULL AND
160+
delegator IS NOT NULL
161+
WHEN 'delegate-stack-extend' THEN
162+
extend_count IS NOT NULL AND
163+
unlock_burn_height IS NOT NULL AND
164+
delegator IS NOT NULL
165+
WHEN 'stack-aggregation-commit' THEN
166+
reward_cycle IS NOT NULL AND
167+
amount_ustx IS NOT NULL
168+
WHEN 'stack-aggregation-commit-indexed' THEN
169+
reward_cycle IS NOT NULL AND
170+
amount_ustx IS NOT NULL
171+
WHEN 'stack-aggregation-increase' THEN
172+
reward_cycle IS NOT NULL AND
173+
amount_ustx IS NOT NULL
174+
ELSE false
175+
END
176+
)`
177+
);
178+
179+
pgm.createIndex('pox4_events', [
180+
{ name: 'block_height', sort: 'DESC' },
181+
{ name: 'microblock_sequence', sort: 'DESC' },
182+
{ name: 'tx_index', sort: 'DESC' },
183+
{ name: 'event_index', sort: 'DESC' },
184+
]);
185+
186+
pgm.createIndex('pox4_events', 'tx_id');
187+
pgm.createIndex('pox4_events', 'index_block_hash');
188+
pgm.createIndex('pox4_events', 'microblock_hash');
189+
190+
pgm.createIndex('pox4_events', 'stacker');
191+
pgm.createIndex('pox4_events', 'burnchain_unlock_height');
192+
pgm.createIndex('pox4_events', 'pox_addr');
193+
pgm.createIndex('pox4_events', 'delegator');
194+
pgm.createIndex('pox4_events', 'name');
195+
196+
pgm.createIndex('pox4_events', 'delegate_to');
197+
pgm.createIndex('pox4_events', 'unlock_burn_height');
198+
};
199+
200+
/** @param { import("node-pg-migrate").MigrationBuilder } pgm */
201+
exports.down = pgm => {
202+
pgm.dropTable('pox4_events');
203+
};

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"dev:follower": "npm run devenv:build && concurrently npm:dev npm:devenv:follower",
1010
"test": "cross-env NODE_ENV=test jest --config ./tests/jest.config.js --coverage --runInBand",
1111
"test:subnets": "cross-env NODE_ENV=test jest --config ./tests/jest.config.subnets.js --coverage --runInBand",
12-
"test:2.4": "cross-env NODE_ENV=test jest --config ./tests/jest.config.2.4.js --coverage --runInBand",
12+
"test:2.5": "cross-env NODE_ENV=test jest --config ./tests/jest.config.2.5.js --coverage --runInBand",
1313
"test:rosetta": "cross-env NODE_ENV=test jest --config ./tests/jest.config.rosetta.js --coverage --runInBand",
1414
"test:rosetta-construction": "cross-env NODE_ENV=test jest --config ./tests/jest.config.rosetta-construction.js --coverage --runInBand",
1515
"test:rosetta-cli:data": "cross-env NODE_ENV=test STACKS_CHAIN_ID=0x80000000 jest --config ./tests/jest.config.rosetta-cli-data.js --coverage --runInBand",
@@ -24,7 +24,7 @@
2424
"test:watch": "cross-env NODE_ENV=test jest --config ./tests/jest.config.js --watch",
2525
"test:integration": "concurrently \"docker compose -f docker/docker-compose.dev.postgres.yml up --force-recreate -V\" \"cross-env NODE_ENV=test jest --config ./tests/jest.config.js --no-cache --runInBand; npm run devenv:stop:pg\"",
2626
"test:integration:subnets": "concurrently --hide \"devenv:deploy:subnets\" \"npm:devenv:deploy:subnets\" \"cross-env NODE_ENV=test jest --config ./tests/jest.config.subnets.js --no-cache --runInBand; npm run devenv:stop:subnets\"",
27-
"test:integration:2.4": "concurrently --hide \"devenv:deploy-krypton\" \"npm:devenv:deploy-krypton\" \"cross-env NODE_ENV=test jest --config ./tests/jest.config.2.4.js --no-cache --runInBand; npm run devenv:stop-krypton\"",
27+
"test:integration:2.5": "concurrently --hide \"devenv:deploy-krypton\" \"npm:devenv:deploy-krypton\" \"cross-env NODE_ENV=test jest --config ./tests/jest.config.2.5.js --no-cache --runInBand; npm run devenv:stop-krypton\"",
2828
"test:integration:rosetta": "concurrently \"npm:devenv:deploy-krypton\" \"cross-env NODE_ENV=test jest --config ./tests/jest.config.rosetta.js --no-cache --runInBand; npm run devenv:stop-krypton\"",
2929
"test:integration:rosetta-construction": "concurrently \"npm:devenv:deploy-krypton\" \"cross-env NODE_ENV=test jest --config ./tests/jest.config.rosetta-construction.js --no-cache --runInBand; npm run devenv:stop-krypton\"",
3030
"test:integration:rosetta-cli:data": "concurrently \"npm:devenv:deploy-krypton\" \"cross-env NODE_ENV=test STACKS_CHAIN_ID=0x80000000 jest --config ./tests/jest.config.rosetta-cli-data.js --no-cache --runInBand; npm run devenv:stop-krypton\"",

0 commit comments

Comments
 (0)