feat: add staking overview endpoint and mirror pox-5 roll-overs - #2673
feat: add staking overview endpoint and mirror pox-5 roll-overs#2673rafa-stacks wants to merge 6 commits into
Conversation
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
🟡 Changes recommended
In-place bond rollover mutations are neither restored nor replayed during chain reorganizations.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Adds a network-wide PoX-5 staking overview and rollover handling to prevent double-counted positions.
Changes:
- Adds
GET /extended/v3/stakingwith locked STX/BTC totals and chain-tip caching. - Introduces the
rolled_overbond-position status and rollover bookkeeping. - Adds comprehensive endpoint, rollover, expiry, ETag, and fork tests.
File summaries
| File | Description |
|---|---|
tests/api/pox5/staking-overview.test.ts |
Tests overview totals and rollover behavior. |
tests/api/pox5/signer-stakers.test.ts |
Updates fixture ordering for single live positions. |
tests/api/pox5/bonds.test.ts |
Updates bond summary rollover expectations. |
src/datastore/v3/types.ts |
Defines staking total result types. |
src/datastore/v3/pg-store-v3.ts |
Queries network-wide locked totals. |
src/datastore/pg-write-store.ts |
Implements rollover bookkeeping and lock recomputation. |
src/datastore/common.ts |
Adds the rolled-over database status. |
src/api/serializers/v3/bonds.ts |
Serializes the new status. |
src/api/schemas/v3/entities/staking-overview.ts |
Defines the overview response schema. |
src/api/schemas/v3/entities/principal-bond-positions.ts |
Extends the position status schema. |
src/api/routes/v3/staking.ts |
Implements the new endpoint. |
src/api/init.ts |
Registers the staking route. |
Review details
- Files reviewed: 12/12 changed files
- Comments generated: 1
- Review effort level: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
🟡 Changes recommended
Cache invalidation, historical backfill, and multi-block side-fork rollover handling remain incorrect.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (1)
src/datastore/pg-write-store.ts:675
- Selecting rollover candidates from the current canonical view loses rollovers that occur wholly on a side fork. For example, if one non-canonical fork block creates bond A and its next non-canonical block rolls A into bond B (or an STX-only stake), A is excluded here, so no source row is recorded; when the fork later wins, both positions contribute to the aggregates. Persist/replay rollover intent from the fork's own ordered PoX-5 history rather than deriving candidates only from the canonical state at ingestion.
const candidates = await sql<{ bond_index: number }[]>`
SELECT bond_index
FROM principal_bond_positions
WHERE principal = ${staker}
AND canonical = true
AND microblock_canonical = true
AND status <> ${DbPrincipalBondPositionStatus.RolledOver}
AND (btc_locked > 0 OR stx_locked > 0)
${excludeFilter}
- Files reviewed: 13/13 changed files
- Comments generated: 2
- Review effort level: Balanced
There was a problem hiding this comment.
🟡 Changes recommended
Batched side-fork rollovers can subtract the same bond position twice when the fork becomes canonical.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
- Files reviewed: 15/15 changed files
- Comments generated: 1
- Review effort level: Balanced
Adds
GET /extended/v3/staking, a network-wide pox-5 staking overview, and fixes a double-count in the write store when a staker rolls over between pox-5 positions.{ "locked": { "stx": { "stx_only": "88231000000000", "bonds": "3570465300381", "total": "91801465300381" }, "btc": { "total": "23017662628" } } }pox-5 keeps a staker in exactly one live position:
register-for-bondreplaces any earlier bond membership and deletes an STX-only stake (staker-info),stakedeletes a bond membership, and the node carries the single account lock into the new position. The API did not mirror this, so during a roll-over a staker was counted under both the old and the new position (in/principals/:principal/staking, per-bond balances, and now the network totals). This PR mirrors the contract.