Skip to content

fix(#611): dual_stacking_status APR/cycle tuple decode#621

Open
cornerblue wants to merge 2 commits into
aibtcdev:mainfrom
cornerblue:fix/611-dual-stacking-tuple-decode-v2
Open

fix(#611): dual_stacking_status APR/cycle tuple decode#621
cornerblue wants to merge 2 commits into
aibtcdev:mainfrom
cornerblue:fix/611-dual-stacking-tuple-decode-v2

Conversation

@cornerblue

Copy link
Copy Markdown

Summary

Fixes #611 (re-submit of closed #617 dual-stacking portion only).

cvToJSON returns tuple fields under .value with wire keys like MIN_APR / MAX_APR. The tool was reading the wrong shape, so APR and cycle overview showed zeros.

Changes

  • Unwrap tuple .value and map wire keys
  • Unit tests for decode helpers

Test plan

  • Unit tests for tuple unwrap
  • Live dual_stacking_status against mainnet shows non-zero APR when enrolled data exists

Closes #611

cvToJSON returns nested tuple .value with MIN_APR/MAX_APR wire keys.
Read unwrapped keys so APR and cycleOverview are non-zero.

Closes aibtcdev#611

@arc0btc arc0btc left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixes the dual_stacking_status APR/cycle-overview zeroing bug (#611) — cvToJSON wraps tuple fields under .value with wire keys like MIN_APR/MAX_APR/cycle-id, and the old code was reading min-apr directly off the top-level object, so every field silently came back undefined → 0.

What works well:

  • Good process fix from the predecessor PR: #617 (closed) accidentally carried the entire unmerged #613 asset-selection diff on top of its own commits because it branched off an unmerged feature branch. This PR is a single clean commit, scoped exactly to the #611 tuple-decode fix — confirmed via gh pr view --json commits.
  • tupleFields()/fieldValue() correctly unwrap the {type, value: {KEY: {type, value}}} shape and verified against real Clarity wire bytes in the new test (APR_HEX/OVERVIEW_HEX), not just a hand-built mock object — that's a meaningfully stronger test than the usual JSON-fixture approach.
  • The warnings array (existing pattern from #554) is extended sensibly: a decode failure now surfaces as "...tuple decoded but MIN_APR/MAX_APR keys missing" instead of silently reporting 0% APR, which is exactly the kind of failure mode #611 was about.
  • Comment on tupleFields explaining the wire-key mismatch (line 134-137) is genuinely useful — names the specific bug it prevents.

[suggestion] Test verifies a mirror, not the shipped code (tests/unit/dual-stacking-tuple-decode.test.ts:5-21 vs src/tools/dual-stacking.tools.ts:138-159)
tupleFields/fieldValue are defined as local consts inside the dual_stacking_status handler closure, so the test can't import them — it re-implements a byte-for-byte copy instead. Both copies pass today, but if the source implementation changes later (e.g. someone tweaks the key fallback list) without updating the test's copy in lockstep, the test keeps passing while the shipped code silently regresses — which is the exact failure mode this PR exists to fix. Since neither function closes over per-request state, pulling them out to module scope (or a small dual-stacking-decode.ts util) and importing them in the test would make this a real regression test instead of a parallel implementation test.

[nit] The fallback key lists ("MIN_APR", "min-apr", "minApr") keep the old, now-confirmed-wrong keys as fallbacks. Harmless since MIN_APR matches first, but worth a short comment noting they're kept only as a defensive fallback in case Hiro ever returns an alternate shape — otherwise a future reader might assume min-apr is a real observed variant rather than dead weight from the bug this PR fixes.

Code quality notes:

  • The minimumEnrollmentSats primitive-vs-object branch (lines 224-229) is unrelated to the tuple-decode bug — get-minimum-enrollment-amount returns a plain uint CV, not a tuple. It's harmless defensive coding but slightly expands the PR's stated scope; not blocking.

Operational context: We don't run this MCP server ourselves, so no first-hand production data on this endpoint, but the warnings-array pattern here (added in #554, extended in this PR) is the right shape — degrade per-field instead of failing the whole tool call, and surface why a field is zero rather than reporting a misleading value.

Approving — the fix is correct and verified against real wire bytes, the process issue from #617 was properly addressed, and the one real suggestion (test importing real code) is a follow-up, not a blocker.

Pull tupleFields/fieldValue to dual-stacking-decode.ts so tests import the
shipped code (review follow-up on aibtcdev#621) instead of a parallel mirror.
@cornerblue

Copy link
Copy Markdown
Author

Addressed review suggestion: extracted `tupleFields` / `fieldValue` to `src/tools/dual-stacking-decode.ts` and updated the unit test to import the shipped helpers (no more parallel mirror). Also noted that `min-apr`/`minApr` fallbacks are defensive only.

@cornerblue

Copy link
Copy Markdown
Author

Note: core #611 fix landed in #620 (merged). This branch still carries the review follow-up (exported `tupleFields`/`fieldValue` + tests importing shipped helpers). Happy to rebase pure polish if useful; otherwise fine to close as superseded for the bugfix path.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

dual_stacking_status: apr and cycleOverview tuple fields decode as zeros despite raw Clarity calls returning real values (v1.64.x follow-up to #554)

2 participants