Skip to content

Unbreak main: the perps v2 build, the Anchor install, and the Biome check - #130

Merged
mikemaccana merged 4 commits into
mainfrom
claude/fix-perps-v2-build
Aug 20, 2026
Merged

Unbreak main: the perps v2 build, the Anchor install, and the Biome check#130
mikemaccana merged 4 commits into
mainfrom
claude/fix-perps-v2-build

Conversation

@mikemaccana

@mikemaccana mikemaccana commented Aug 20, 2026

Copy link
Copy Markdown
Collaborator

main is red in three independent ways. This PR fixes all three.

1. finance/perpetual-futures does not compile

error: handler context must be passed by mutable reference: use `ctx: &mut Context<T>`

plus eight more behind it, so anchor build fails for the whole project and its 28 tests never run.

perps: let the pool authority retune the funding rate landed on main after the Anchor v2 port and was written against v1: Context<T> rather than &mut Context<T>, Signer<'info>, Box<Account<'info, Pool>>, and has_one = authority.

Nothing caught it. perpetual-futures is not a root workspace member, so neither cargo clippy nor cargo fmt --check has ever seen the crate, and the Anchor workflow only builds projects a push actually touches.

The fix is the usual v2 port: &mut Context<T>, the 'info lifetime dropped, Box<BorshAccount<Pool>> to match every sibling handler, and has_one replaced by address = pool.authority on the signer. Two more things the crate needed for the same reason nobody had looked at it: #[instruction(side: Side)] warns as an unused variable under v2's #[derive(Accounts)] expansion so it takes the leading underscore the other examples use, and main's new lending and perps test code was never formatted.

2. The Anchor workflow cannot install Anchor

Runs on main were green only because they hit a warm toolchain cache and skipped the install entirely. That cache is gone, and the install underneath it does not work:

Error: No prebuilt binary found for version `2.0.0-rc.1` (HTTP 404).

avm has no prebuilt binary for this pre-release. Its --from-source path is not a substitute: it builds the CLI from the v2.0.0-rc.1 git tag, which is not the same code as the anchor-lang 2.0.0-rc.1 published on crates.io that every program here compiles against. I tried that first and it took anchor build down across half the repository with cannot find trait IdlBuild in crate anchor_lang and missing field variants, both out of anchor idl build, on projects that have nothing wrong with them.

crates.io publishes anchor-cli 2.0.0-rc.1 alongside the library, so the workflow now installs it from there with --locked and drops avm. avm is a version manager and this workflow pins one version, so it was not earning its place. The cache key changes with the install method, so no run can resurrect a binary built the old way.

3. Biome fails on a regenerated IDL

biome check ./ formats JSON as well as TypeScript. anchor build regenerated basics/cross-program-invocation/anchor/idls/lever.json with one array element per line, and Biome puts those on a single line, so the TypeScript workflow has failed on every commit since. Formatting only; the IDL's contents are unchanged, so declare_program! and the LiteSVM tests that read it see what they saw before.

Verification

Locally: cargo check, cargo clippy -- -D warnings and cargo fmt --check are clean on perpetual-futures; repository-wide cargo fmt --all --check and cargo clippy -- -D warnings -A clippy::diverging_sub_expression pass; biome check over the 155 tracked files CI sees reports zero errors.

Because this touches .github/workflows/anchor.yml, the changes job builds every Anchor project rather than the few this diff touches, so each run here is a full 55-project sweep.

On the mismatched-CLI run, perpetual-futures got past the compile error this PR exists to fix and died at the same IDL stage as everyone else, with no perpetual_futures compile diagnostic anywhere in the log; escrow and lending, in the same group, built and tested clean. The sweep on the corrected toolchain is what will confirm it end to end.

Relationship to #128

#128 carries the perpetual-futures fix as one commit among a ~100-file change that adds every Anchor program to the root workspace. Here it is on its own, so it can land without waiting on that review. The file contents are identical, so whichever merges second is a no-op for those hunks.

The remaining known breakage, the ASM workflow's cargo install --git .../sbpf.git picking between two binaries after upstream added an xtask crate, is not included here: ASM does not run on this PR, so it is not blocking. That fix sits on claude/docs-match-implementation.

`perps: let the pool authority retune the funding rate` landed on main after
the v2 port and was written against v1: `Context<T>` rather than
`&mut Context<T>`, `Signer<'info>`, `Box<Account<'info, Pool>>`, and
`has_one = authority`. The crate does not compile, so `anchor build` fails
for the whole project and its 28 tests never run.

Nothing caught it because `perpetual-futures` is not a root workspace member,
so neither `cargo clippy` nor `cargo fmt --check` has ever seen the crate, and
the Anchor workflow only builds projects a push actually touches.

The port is the usual set: `&mut Context<T>`, the `'info` lifetime dropped,
`Box<BorshAccount<Pool>>` to match every sibling handler, and `has_one`
replaced by `address = pool.authority` on the signer.

Two more things the crate needed, for the same reason nobody had looked at it:
`#[instruction(side: Side)]` warns as an unused variable under v2's
`#[derive(Accounts)]` expansion, so it takes the leading underscore the other
examples use, and main's new lending and perpetual-futures test code was
never formatted.

`cargo check` and `cargo clippy -- -D warnings` are both clean on the crate
now. The LiteSVM tests still need `cargo build-sbf` to produce the `.so` they
embed, which CI does and this change does not affect.

Copy link
Copy Markdown
Collaborator Author

Status on this branch: Rustfmt, Clippy, and all eight Kani proof jobs are green. The Anchor build-and-test job is still running, and it is the one that actually proves the fix.

Biome check is red, and it is red on main too. It is not caused by this change. basics/cross-program-invocation/anchor/idls/lever.json was regenerated by anchor build with one array element per line, and biome check ./ reformats those onto a single line, so the TypeScript workflow has failed on every commit since the IDL was last regenerated. The ASM workflow is also red on main, for an unrelated reason: cargo install --git .../sbpf.git now finds two binaries after upstream added an xtask crate, and refuses to pick between them.

Both fixes are written and sitting on claude/docs-match-implementation. I have kept them off this PR so it stays the one-thing change its title describes. Happy to fold them in here instead if you would rather unbreak all three at once.


Generated by Claude Code

…inary

The Anchor job died in its install step:

    Error: No prebuilt binary found for version `2.0.0-rc.1` (HTTP 404).
    Try `avm install 2.0.0-rc.1 --from-source`.

No project was built, and the summary step then failed to read a
failed_projects.txt that nothing had written. Earlier runs passed on a warm
toolchain cache, which skipped the install entirely and hid this; any run
that misses the cache hits it.

Taking avm's own suggestion. The source build is slow, and the existing cache
keyed on the version is what keeps it off the critical path after the first
run.

Copy link
Copy Markdown
Collaborator Author

The Anchor job failed, but not on the code. It died in its install step before building anything:

Error: No prebuilt binary found for version `2.0.0-rc.1` (HTTP 404).
Try `avm install 2.0.0-rc.1 --from-source`.

The summary step then failed to read a failed_projects.txt that nothing had written. Earlier runs on main passed because they hit the warm toolchain cache and skipped the install entirely; any run that misses that cache hits this. So the repository's main test workflow is one cache eviction away from red regardless of this PR.

Taken avm's own suggestion in 5fbd062: avm install 2.0.0-rc.1 --from-source. The source build is slow, and the existing cache keyed on the version keeps it off the critical path after the first run.

One consequence worth knowing: the changes job builds every project when the workflow file itself is touched, so this run is a full sweep of all 55 Anchor projects rather than the handful this diff touches. That is the run that will actually prove the perpetual-futures fix.


Generated by Claude Code

The TypeScript workflow runs `biome check ./`, which formats JSON as well as
TypeScript. `anchor build` regenerated
`basics/cross-program-invocation/anchor/idls/lever.json` with one array
element per line, and Biome puts those on a single line, so the check has
failed on every commit since the IDL was last regenerated. `main` is red on
this today.

Formatting only; the IDL's contents are unchanged, so `declare_program!` and
the LiteSVM tests that read it see exactly what they saw before.
@mikemaccana mikemaccana changed the title perps: fix the v2 build break in set_funding_rate Unbreak main: the perps v2 build, the Anchor install, and the Biome check Aug 20, 2026
The previous commit's `avm install --from-source` was the wrong fix. avm
builds the CLI from the `v2.0.0-rc.1` git tag, which is not the same code as
the `anchor-lang` 2.0.0-rc.1 published on crates.io that every program here
compiles against. The CLI and the library disagreed about the IDL, and
`anchor build` failed across roughly half the projects for reasons that had
nothing to do with the projects:

    error[E0405]: cannot find trait `IdlBuild` in crate `anchor_lang`
    Error: missing field `variants` at line 1 column 15428

Both come from `anchor idl build`: the CLI emits a shim referencing a trait
the published crate does not have, and writes IDL JSON its own parser then
rejects.

crates.io publishes `anchor-cli` 2.0.0-rc.1 alongside the library, so
installing it there keeps the two on one release. avm is a version manager
and this workflow pins a single version, so it was not buying anything.
`--locked` builds the CLI against its own published lockfile so the result
does not drift with the registry.

The cache key changes with the install method, so a run cannot resurrect a
binary built the old way.

Copy link
Copy Markdown
Collaborator Author

Correcting my earlier comment: avm install --from-source was the wrong fix, and the wall of red on the last run is my doing, not 20 latent bugs.

avm builds the CLI from the v2.0.0-rc.1 git tag, which is not the same code as the anchor-lang 2.0.0-rc.1 published on crates.io that every program here compiles against. The two disagree about the IDL, so anchor build failed in seven of the fourteen groups on projects that have nothing wrong with them:

error[E0405]: cannot find trait `IdlBuild` in crate `anchor_lang`
Error: missing field `variants` at line 1 column 15428

Both come out of anchor idl build: the CLI emits a shim referencing a trait the published crate does not have, and writes IDL JSON its own parser then rejects.

crates.io publishes anchor-cli 2.0.0-rc.1 alongside the library, so 95b839b installs it from there and drops avm entirely. avm is a version manager and this workflow pins one version, so it was not earning its place. The cache key changes with the install method so no run can resurrect a binary built the old way.

The perpetual-futures fix itself looks good. In that run it got past the compile error this PR exists to fix and died at the same IDL stage as everyone else, with no perpetual_futures compile diagnostic anywhere in the log. escrow and lending, in the same group, built and tested clean.

One thing worth flagging separately: main was only ever green here because it hit a warm toolchain cache. That cache is gone, and the prebuilt binary avm wants for this pre-release 404s, so main's Anchor workflow is red on its own right now regardless of this PR.


Generated by Claude Code

Copy link
Copy Markdown
Collaborator Author

The sweep finished. Correcting my previous comment first: I claimed the IdlBuild error class was gone after the crates.io CLI change. It was not. I generalised from one group's log. The crates.io install is still the right arrangement (it removes the 404 and drops avm), but it did not change the IDL failures, and my "CLI built from a different fork" diagnosis was wrong: the v2.0.0-rc.1 tag resolves to the same commit the crates.io release was cut from.

Result: 9 of 55 projects fail, every one of them at anchor idl build

Everything else is green, including Biome, Rustfmt, Clippy and all eight Kani jobs.

Two distinct families.

Family A, "has no IDL type information" (3 projects). A type reaching the IDL has no v2 IDL derive.

  • basics/pyth — the vendored PriceUpdateV2
  • finance/vault-strategymock_swap_router::AssetRate
  • finance/order-bookordertree.rs:37 still carries impl anchor_lang::IdlBuild for OrderTreeRoot {}, and IdlBuild does not exist in anchor-lang v2

These are ours. The v2 port missed them, and docs/anchor-v2-migration.md has no entry for IdlBuild.

Family B, "missing field variants" (6 projects, 7 counting order-book which has both). Anchor's IDL parser rejecting JSON its own generator just wrote: a type def with "kind": "enum" and no variants key.

A census of all 55 projects makes the pattern exact:

declares an IdlType enum does not
fails on variants 7 0
passes 0 48

Every project in the repository that declares an enum with #[derive(..., IdlType, ...)] fails. No project without one does. The enums are unremarkable and varied: EventStatus (three unit variants), OrderSide/OrderStatus, AnchorField (three unit variants plus Key(String)).

The data cannot separate two explanations, and both matter for what to do next:

  1. #[derive(IdlType)] on enums is broken in 2.0.0-rc.1, in which case nothing here is wrong and the fix is an Anchor release.
  2. v2 needs something alongside IdlType on enums that all seven are missing, in which case it is one recipe change applied seven times.

Distinguishing them needs one anchor idl build run against a trivial enum, which I cannot do: release.anza.xyz is blocked by this session's egress proxy, so I cannot install Anchor or run the IDL build locally at all. Everything above is from CI plus a local census.

Why none of this was visible

idl-build is a Cargo feature nothing turns on except anchor idl build. cargo check, cargo clippy, cargo fmt and the Rustfmt/Clippy jobs are all structurally blind to code behind it, which is how order-book's IdlBuild impls survived the port. And anchor build had effectively stopped running: the workflow only builds projects a push touches, and its toolchain install has been broken behind a cache that hid it. This run is the first full sweep in a long time, which is why nine projects surfaced at once.

Suggestion

Land this PR for what it does fix, and track the IDL work separately. It fixes three things that are broken on main today and blocks nothing:

  • finance/perpetual-futures no longer fails to compile. Its original error is gone; it now fails at the IDL stage alongside six unrelated projects, so it is no longer a perps-specific problem.
  • The Anchor workflow can install Anchor again. main cannot right now.
  • Biome passes.

Merging leaves nine projects failing on anchor idl build, which is the same nine that would fail on main the moment its toolchain install is repaired. This PR does not cause them and does not make them worse.


Generated by Claude Code

@mikemaccana
mikemaccana merged commit 333c226 into main Aug 20, 2026
34 of 41 checks passed
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