Skip to content

fix: repair three CI-broken native programs#631

Open
NikkiAung wants to merge 2 commits into
solana-foundation:mainfrom
NikkiAung:fix/ci-broken-native-programs
Open

fix: repair three CI-broken native programs#631
NikkiAung wants to merge 2 commits into
solana-foundation:mainfrom
NikkiAung:fix/ci-broken-native-programs

Conversation

@NikkiAung

@NikkiAung NikkiAung commented Jul 10, 2026

Copy link
Copy Markdown

Summary

  • cross-program-invocation/native: bump borsh 1.5.7→1.6.1, borsh-derive 1.5.7→1.6.1, solana-program 3.0→4.0 in hand and lever Cargo.toml — the isolated workspace was pinning stale versions that conflict with the rest of the workspace
  • realloc/native: migrate ts/ from borsh v1 Map-based API to borsh v2 {struct:...} schema; add missing "borsh": "^2.0.0" direct dependency (it was absent from package.json, making the import unresolvable); fix isSigner: false→true on target account in createCreateInstruction (was causing MissingRequiredSignature on the create_account CPI); fix CJS require("node:fs") → ESM import in util.ts
  • favorites/native: fix u64 assertion (new BN(number as Buffer, "le")Number(favoritesData.number) since borsh v2 deserializes u64 as bigint); fix "wrong seeds" test which was deriving the correct PDA and expecting failure — changed to use a genuinely wrong seed so the on-chain check actually rejects it

Test plan

  • CI runs pnpm build-and-test for cross-program-invocation/native — Rust build with updated deps passes, TS test passes
  • CI runs pnpm build-and-test for realloc/native — Rust build passes, borsh v2 serialization works at runtime, create_account CPI succeeds with correct signer flag
  • favorites/native test logic fixes visible in diff; full CI validation pending .ghaignore removal once bankrun/SBF compatibility is confirmed on current platform-tools

@NikkiAung
NikkiAung requested a review from dev-jodee as a code owner July 10, 2026 20:49
@greptile-apps

greptile-apps Bot commented Jul 10, 2026

Copy link
Copy Markdown

Greptile Summary

This PR fixes three CI-broken native Solana programs by bumping Rust dependencies, migrating TypeScript code from borsh v1 to v2, and correcting several test/instruction bugs.

  • cross-program-invocation/native: Bumps borsh 1.5.7→1.6.1 and solana-program 3.0→4.0 in both hand and lever Cargo manifests to align with the workspace.
  • realloc/native: Migrates all borsh schemas from the v1 Map-based API to the v2 {struct:{…}} object form, adds the missing borsh direct dependency to package.json, fixes isSigner: false→true on the target account (required for SystemProgram.createAccount where the new account must sign), and replaces a CJS require() call with a proper ESM import.
  • favorites/native: Corrects the u64 assertion (new BN(…)Number(…) matching borsh v2's BigInt return) and fixes the "wrong seeds" negative test so it actually submits an unrecognized PDA and hoists the assertion outside the catch block.

Confidence Score: 5/5

All changes are targeted, well-scoped bug fixes; no correctness-breaking issues were found.

The dependency bumps, borsh v2 migration, isSigner fix, and test logic corrections are all consistent with their stated goals and verified against the Rust program and test harness. The two observations (libc fields in the lockfile, class-vs-plain-object in fromBuffer) are non-blocking in the current usage and don't affect runtime behaviour of the tests being fixed.

basics/realloc/native/pnpm-lock.yaml — the removed libc filter fields are worth a second look if CI ever runs on musl-based Linux.

Important Files Changed

Filename Overview
basics/realloc/native/ts/instructions/create.ts Migrated to borsh v2 schema; fixed isSigner: true on target so the SystemProgram.createAccount CPI signer check passes
basics/favorites/native/tests/test.ts Fixed u64 BigInt assertion and negative test — threw flag is now correctly set outside the catch block
basics/realloc/native/package.json Adds the missing borsh ^2.0.0 direct dependency that was previously absent, causing unresolvable imports
basics/realloc/native/pnpm-lock.yaml Adds borsh@2.0.0 snapshot; removes libc filter fields from solana-bankrun optional native packages — likely a workaround for pnpm platform detection on CI
basics/realloc/native/ts/util/util.ts Replaced CJS require() with a proper ESM static import for readFileSync
basics/realloc/native/ts/state/address-info.ts Migrated AddressInfoSchema to borsh v2 struct form; fromBuffer now uses the two-arg deserialize API
basics/cross-program-invocation/native/programs/hand/Cargo.toml Bumps borsh 1.5.7→1.6.1 and solana-program 3.0→4.0 to match workspace versions
basics/cross-program-invocation/native/programs/lever/Cargo.toml Bumps borsh 1.5.7→1.6.1 and solana-program 3.0→4.0 to match workspace versions

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    subgraph favorites["favorites/native"]
        F1["Test: wrong seeds\n(was: correct PDA → never failed)"] -->|"fix: use 'wrong_seed' PDA"| F2["On-chain seed check rejects → tx throws"]
        F3["u64 assertion\n(was: new BN(buffer, 'le'))"] -->|"fix: Number(bigint)"| F4["borsh v2 returns BigInt\n→ Number() converts safely"]
    end

    subgraph realloc["realloc/native"]
        R1["Missing borsh dep in package.json"] -->|"add borsh ^2.0.0"| R2["Import resolves ✓"]
        R3["borsh v1 Map schema"] -->|"migrate to v2 struct schema"| R4["borsh.serialize/deserialize v2 API ✓"]
        R5["target isSigner: false\n→ MissingRequiredSignature CPI error"] -->|"fix: isSigner: true"| R6["testAccount signs tx\n→ SystemProgram.createAccount succeeds ✓"]
        R7["CJS require('node:fs')"] -->|"fix: ESM static import"| R8["import readFileSync from 'node:fs' ✓"]
    end

    subgraph cpi["cross-program-invocation/native"]
        C1["borsh 1.5.7 / solana-program 3.0\n(stale, conflicts with workspace)"] -->|"bump versions"| C2["borsh 1.6.1 / solana-program 4.0 ✓"]
    end
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    subgraph favorites["favorites/native"]
        F1["Test: wrong seeds\n(was: correct PDA → never failed)"] -->|"fix: use 'wrong_seed' PDA"| F2["On-chain seed check rejects → tx throws"]
        F3["u64 assertion\n(was: new BN(buffer, 'le'))"] -->|"fix: Number(bigint)"| F4["borsh v2 returns BigInt\n→ Number() converts safely"]
    end

    subgraph realloc["realloc/native"]
        R1["Missing borsh dep in package.json"] -->|"add borsh ^2.0.0"| R2["Import resolves ✓"]
        R3["borsh v1 Map schema"] -->|"migrate to v2 struct schema"| R4["borsh.serialize/deserialize v2 API ✓"]
        R5["target isSigner: false\n→ MissingRequiredSignature CPI error"] -->|"fix: isSigner: true"| R6["testAccount signs tx\n→ SystemProgram.createAccount succeeds ✓"]
        R7["CJS require('node:fs')"] -->|"fix: ESM static import"| R8["import readFileSync from 'node:fs' ✓"]
    end

    subgraph cpi["cross-program-invocation/native"]
        C1["borsh 1.5.7 / solana-program 3.0\n(stale, conflicts with workspace)"] -->|"bump versions"| C2["borsh 1.6.1 / solana-program 4.0 ✓"]
    end
Loading

Reviews (3): Last reviewed commit: "fix: correct negative test logic in favo..." | Re-trigger Greptile

Comment on lines 138 to 143
try {
await client.processTransaction(tx);
console.error("Expected the test to fail");
assert(false, "Expected transaction to fail with wrong PDA seeds");
} catch (_err) {
assert(true);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Negative test always passes — assertion swallowed by catch

assert(false, ...) inside the try block throws an AssertionError, but the catch (_err) clause catches it indiscriminately and then calls assert(true), so the test passes whether processTransaction succeeds or throws. If the program ever stops rejecting wrong seeds, this test will still show green. Consider restructuring to hoist the assertion outside the catch:

let failed = false;
try {
  await client.processTransaction(tx);
} catch {
  failed = true;
}
assert(failed, "Expected transaction to fail with wrong PDA seeds");

@dev-jodee dev-jodee left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

needs signed commits

@NikkiAung
NikkiAung force-pushed the fix/ci-broken-native-programs branch from c137f1e to 10ca60c Compare July 21, 2026 00:40
@NikkiAung

Copy link
Copy Markdown
Author

@dev-jodee All commits have been re-signed with an SSH signing key and now show as Verified on GitHub. Thanks for the heads up!

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