Skip to content

fix(bindings): regenerate stale ABI JSONs + honor FOUNDRY_OUT in gen-bindings#206

Merged
drewstone merged 1 commit into
mainfrom
fix/bindings-abi-stale-out-dir
Jul 7, 2026
Merged

fix(bindings): regenerate stale ABI JSONs + honor FOUNDRY_OUT in gen-bindings#206
drewstone merged 1 commit into
mainfrom
fix/bindings-abi-stale-out-dir

Conversation

@drewstone

Copy link
Copy Markdown
Contributor

Latent bug that a 0.19 publish would have shipped. cargo xtask gen-bindings copied bindings/abi/*.json from a hardcoded out/local-build/, so any FOUNDRY_OUT-redirected build (required when the default out/ is root-owned — a recurring condition) left the .rs bindings fresh but the abi JSONs stale from a pre-0.19 build. The committed abi still advertised removed functions (blueprintSources, canScheduleExit) and a fat getSlashProposal tuple (proposedAt/disputeReason/disputedAt) — and those abi JSONs are exactly what the dapp syncs.

Caught while wiring the dapp for 0.19 (its ABIs didn't match the source).

Fix: source the abi copy from the same out dir the build wrote to (std::env FOUNDRY_OUT, default out/local-build), and regenerate. The abi now matches 0.19: blueprintSources/canScheduleExit/getBlueprintRecord absent, getSlashProposal free of the removed fields. Verified by parsing the regenerated ITangleFull.json. The .rs bindings were already correct (forge bind read the fresh dir).

…bindings

The xtask copied bindings/abi/*.json from a HARDCODED `out/local-build/...`, so any
FOUNDRY_OUT-redirected `gen-bindings` (which is required whenever the default `out/`
is root-owned/unwritable — a recurring condition on this checkout) left the .rs
bindings fresh but the abi/*.json STALE from a pre-0.19 build. Result: the committed
abi JSONs still advertised removed functions (blueprintSources, canScheduleExit) and
a fat getSlashProposal tuple (proposedAt/disputeReason/disputedAt) — the ABIs the
dapp syncs. Publishing would have shipped these wrong ABIs.

Fix: source the abi copy from the SAME out dir the build wrote to
(std::env FOUNDRY_OUT, default out/local-build). Regenerate: the abi JSONs now match
the 0.19 contracts (blueprintSources/canScheduleExit/getBlueprintRecord absent;
getSlashProposal free of the removed timestamp/reason fields).

Verified: ITangleFull.json + the 6 other synced ABIs regenerated from the fresh
artifacts; forge bind .rs unchanged (it was already reading the fresh dir).

@tangletools tangletools 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.

✅ Auto-approved drewstone PR — 9e9ca52c

This PR was opened by the trusted drewstone account.
The full PR reviewer audit still runs separately and will publish findings if it detects issues.

tangletools · auto-approval · reason: drewstone_author · 2026-07-07T20:49:42Z

@tangletools tangletools 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.

🟡 Value Audit — sound-with-nits

Verdict sound-with-nits
Concerns 1 (1 weak-concern)
Heuristic 0.0s
Duplication 0.0s
Interrogation 120.2s (2 bridge agents)
Total 120.2s

💰 Value — sound-with-nits

Fixes a real stale-ABI bug by making cargo xtask gen-bindings copy ABI JSONs from the same Foundry output directory that the build wrote to (honoring FOUNDRY_OUT), and regenerates the 0.19 ABIs so they match the source.

  • What it does: Changes xtask/src/main.rs:167 to read FOUNDRY_OUT from the environment and fall back to out/local-build, instead of hardcoding out/local-build in every ABI copy path. It also regenerates the committed ABI JSONs in bindings/abi/ so they reflect the current 0.19 contract source (e.g., SlashProposal no longer contains the removed proposedAt, disputeReason, or disputedAt fields).
  • Goals it achieves: Ensures that a FOUNDRY_OUT-redirected build no longer silently copies stale ABI JSONs while producing fresh .rs bindings. This prevents shipping bindings whose JSON ABIs advertise removed functions/fields, which is what the dapp consumes.
  • Assessment: Good change. It fixes a coherent latent bug that would have shipped a 0.19 release with stale ABIs, and it does so in the grain of the existing Rust xtask/Foundry toolchain. The regenerated ABI JSONs now match the source struct definitions (src/libraries/SlashingLib.sol:46-70).
  • Better / existing approach: none — this is the right approach. The only alternative would be parsing foundry.toml to derive the default out value instead of hardcoding out/local-build, but that adds TOML parsing complexity for minimal gain; honoring FOUNDRY_OUT is the standard Foundry contract and solves the reported failure mode.
  • Model: opencode/kimi-for-coding/k2p7
  • Bridge attempts: 1

🎯 Usefulness — sound

Correct 1-line fix making the ABI-copy step honor FOUNDRY_OUT like forge already does, plus regenerated 0.19 ABI JSONs that the dapp syncs — prevents a stale-ABI publish.

  • Integration: The gen-bindings xtask is the documented canonical bindings generator (xtask/README.md, CLAUDE.md). bindings/abi/.json ship in the published crate (Cargo.toml:14-21 include = abi/**/) and are synced by the dapp; TNT_CORE_VERSION is exposed at bindings/src/lib.rs:26. The fix targets the single code path (ABI copy at xtask/src/main.rs:167-199) that was inconsistent with the forge build/bind calls
  • Fit with existing patterns: Fits the grain precisely. It is a minimal behavioral fix to an existing code path — reads the same env var foundry itself uses (FOUNDRY_OUT), with a default that matches the profile config (foundry.toml:45 out = "out/local-build"). No new abstraction, no competing pattern; it removes a hardcoded path that diverged from how the surrounding forge invocations already resolved output.
  • Real-world viability: Holds up on the redirected-build path it was written for: foundry's FOUNDRY_OUT replaces the whole out path (the profile subdir name is already baked into the foundry.toml out = setting), so repo_root.join(out_dir).join(rel) resolves identically to where forge build wrote. Rust Command::env overrides only the named var, so forge children inherit the parent FOUNDRY_OUT. Both relative and absolute F
  • Model: opencode/zai-coding-plan/glm-5.2
  • Bridge attempts: 1

💰 Value Audit

🟡 Default output dir is hardcoded in both foundry.toml and xtask [maintenance] ``

The fallback out_dir defaults to out/local-build (xtask/src/main.rs:167), which matches foundry.toml:45 only by convention. If the local_build profile's out value changes, non-FOUNDRY_OUT builds will silently copy from the wrong place again. Consider reading foundry.toml or running forge config to derive the default when FOUNDRY_OUT is unset.


What this audit checks

It judges the change on its merits — not whether it was tasked out in an issue. Unticketed, fast-moving work is fine; the question is whether the change is good and whether a better or existing approach should be used instead.

Pass What it asks
Heuristic Vague title? Whitespace-only or cruft-bearing diff? (content signals only)
Duplication Do added function/class names already exist elsewhere in the repo?
Value Audit What does it do? What goal does it achieve? Is it good? Better architecture or already-exists?
Usefulness Audit Does it integrate and fit? Will it hold up in real use and actually get used?

Findings are concerns, not blocks — the human reviewer decides what to do with them.

value-audit · 20260707T205709Z

@tangletools

Copy link
Copy Markdown
Contributor

✅ No Blockers — 9e9ca52c

Review health 100/100 · Reviewer score 82/100 · Confidence 75/100 · 2 findings (1 medium, 1 low)

deepseek kimi-code aggregate
Readiness 95 82 82
Confidence 75 75 75
Correctness 95 82 82
Security 95 82 82
Testing 95 82 82
Architecture 95 82 82

Reviewer score is advisory once the run is complete and the verdict has no blockers.

Full multi-shot audit completed 3/3 planned shots over 9 changed files. Global verifier still owns final merge decision. | Full multi-shot audit completed 3/3 planned shots over 9 changed files. Global verifier still owns final merge decision.

🟠 MEDIUM Stale TNT_CORE_VERSION hash — bindings/TNT_CORE_VERSION

Line 1 contains 691c7c7 (#203), which is an ancestor of both the PR base (69d3a0f...) and head (9e9ca52...). The PR modifies bindings/abi/.json and bindings/src/bindings/.rs, so the version stamp should reflect the commit from which those bindings were generated. Because TNT_CORE_VERSION was not updated, downstream consumers and release tooling will misreport the source commit. Fix by regenerating bindings with xtask (or setting TNT_CORE_VERSION_OVERRIDE to the PR head) so the file matches the actual source commit.

🟡 LOW Breaking ABI surface changes in generated interface ABIs — bindings/abi/ITangle.json

Concrete evidence: ITangle.json removed function selectors blueprintSources(uint64) and canScheduleExit(uint64,address), and getOperatorRegistration now returns a tuple with only registeredAt (uint64). IBlueprintServiceManager.json changed onJobResult from (uint64,uint8,uint64,address,bytes,bytes) to (uint64,uint8,uint64,address,bytes32,bytes). MultiAssetDelegation.json removed getOperatorSlashFactor(address,bytes32). These are intentional source-driven changes, but any downstream caller using the old selectors will revert. The PR already updates bindings/src Rust bindings, but external SDK/TS consumers must be aligned before relying on these ABIs.


tangletools · 2026-07-07T21:03:06Z · trace

@tangletools tangletools 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.

✅ Approved — 2 non-blocking findings — 9e9ca52c

Full multi-shot audit completed 3/3 planned shots over 9 changed files. Global verifier still owns final merge decision. | Full multi-shot audit completed 3/3 planned shots over 9 changed files. Global verifier still owns final merge decision.

Full immutable report for this review: trace

Summary comment for this run: full summary


tangletools · 2026-07-07T21:03:06Z · immutable trace

@drewstone drewstone merged commit 5925bec into main Jul 7, 2026
1 check passed
@drewstone drewstone deleted the fix/bindings-abi-stale-out-dir branch July 7, 2026 22:21
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.

2 participants