Skip to content

test(sealevel): backward compat e2e with old core programs#8135

Closed
tkporter wants to merge 32 commits intomainfrom
trevor/solana-update-deps-tests
Closed

test(sealevel): backward compat e2e with old core programs#8135
tkporter wants to merge 32 commits intomainfrom
trevor/solana-update-deps-tests

Conversation

@tkporter
Copy link
Copy Markdown
Member

Summary

Opening this to run additional CI tests on the Solana SDK v3.x migration (#7999).

  • Downloads old core .so files from the sealevel-v1.0.0 release for sealeveltest1/sealeveltest2
  • Deploys new locally-built .so files for sealeveltest3
  • Verifies new agents (relayer, validator, scraper) work with old on-chain programs
  • Tests old→old message flow (sealeveltest1 → sealeveltest2) and old→new (sealeveltest1 → sealeveltest3)
  • Cleans up RPC client test (uses #[ignore] with real mainnet slot)

Test plan

  • Sealevel e2e test passes in CI
  • All 12 messages delivered (6→sealeveltest2 with old programs, 6→sealeveltest3 with new programs)

🤖 Generated with Claude Code

tkporter and others added 15 commits February 2, 2026 16:21
This is a major migration from the forked Solana v1.14.13 dependencies to
official Solana SDK v3.x releases. The migration enables building programs
with modern tooling and removes the need for forked Solana dependencies.

## Workspace Configuration

- Added `resolver = "2"` to rust/sealevel/Cargo.toml
  - Critical fix for proper Cargo feature unification
  - Prevents getrandom 0.3.x from being pulled in incorrectly
  - Ensures dev-dependency features don't leak into SBF builds

- Updated dependency versions:
  - solana-program: 1.14.13 → 3.0.0
  - solana-sdk: 1.14.13 → 3.0.0
  - solana-client: 1.14.13 → 3.0.7
  - solana-program-test: 1.14.13 → 3.0.7
  - spl-token: 3.x → 9.0
  - spl-token-2022: 0.x → 10.0
  - spl-associated-token-account: 1.x → 8.0
  - prometheus: 0.13 → 0.14 (required for protobuf 3 compat)
  - protobuf: "*" → 3 (pinned for stability)

- Replaced forked solana-* dependencies with official crates

- Added new interface crates (SDK v3 module split):
  - solana-system-interface
  - solana-compute-budget-interface
  - solana-loader-v3-interface
  - solana-commitment-config
  - solana-stake-interface

## API Migration

### BorshIoError Signature Change
Changed from `BorshIoError(String)` to unit variant `BorshIoError`.
Affected ~40 locations across:
- programs/mailbox/src/instruction.rs
- programs/validator-announce/src/instruction.rs
- programs/hyperlane-sealevel-igp/src/instruction.rs
- libraries/account-utils/src/*.rs
- libraries/message-recipient-interface/src/lib.rs
- libraries/interchain-security-module-interface/src/lib.rs
- libraries/hyperlane-sealevel-connection-client/src/lib.rs

### Keccak API Changes
The keccak module API changed from streaming hasher to direct functions:
- `keccak::Hasher::default() + hash() + result()` → `keccak::hash()`
- For multiple inputs: → `keccak::hashv(&[...])`

Files affected:
- libraries/ecdsa-signature/src/lib.rs
- programs/validator-announce/src/instruction.rs

### AccountInfo::new() Parameter Removal
Removed the `rent_epoch` (Epoch) parameter from AccountInfo::new() calls.
Previously 8 params, now 7 params. Affected test code in:
- libraries/access-control/src/lib.rs (6 occurrences)

### System Program Import
Changed from `solana_program::system_program` to `solana_system_interface::program`.
Affected all programs and libraries that interact with system program.

### Instruction Imports
Changed `solana_program::loader_v3_instruction` to
`solana_loader_v3_interface::instruction` for BPF loader interactions.

### Clock/Sysvar Changes
Updated sysvar imports from `solana_program::sysvar` to use the new
module organization where applicable.

## Program Build Configuration

- Updated build-programs.sh: SOLANA_CLI_VERSION 2.2.1 → 3.0.14
- Added `#![allow(unexpected_cfgs)]` to all program lib.rs files
  - Required for Solana's custom cfg values: target_os="solana",
    feature="custom-heap", feature="custom-panic"

- Added `getrandom = { workspace = true, features = ["custom"] }` to
  all program Cargo.toml files
  - Required for SBF determinism (programs must use custom RNG)

- Updated rust-toolchain to nightly-2025-01-15 (required for SDK v3)

## Programs Successfully Building

All 7 production programs now build with `cargo build-sbf`:
- hyperlane_sealevel_mailbox.so (176KB)
- hyperlane_sealevel_igp.so (235KB)
- hyperlane_sealevel_multisig_ism_message_id.so (161KB)
- hyperlane_sealevel_token.so (319KB)
- hyperlane_sealevel_token_collateral.so (324KB)
- hyperlane_sealevel_token_native.so (298KB)
- hyperlane_sealevel_validator_announce.so (129KB)

## rust/main Compatibility Updates

Updated rust/main/Cargo.toml for shared dependency compatibility:
- prometheus: 0.13 → 0.14
- protobuf: "*" → 3

Note: Full rust/main migration (Phase 3) is pending. The changes here
maintain compatibility between both workspaces.

## Next Steps

- Phase 3: Complete rust/main migration (ed25519-dalek API changes)
- Phase 4: Run E2E tests to validate program functionality
- Phase 5: Evaluate non-Solana patches in rust/main

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Updates rust/main crates to work with Solana SDK v3.x:

- Add new Solana interface crate dependencies:
  - solana-commitment-config
  - solana-compute-budget-interface
  - solana-rpc-client
  - solana-sdk-ids
  - solana-system-interface

- Update API calls for v3.x:
  - Pubkey::new() -> Pubkey::try_from()
  - Signature::new() -> Signature::try_from()
  - Keypair::from_bytes() -> Keypair::try_from()
  - Memcmp struct init -> Memcmp::new()
  - borsh try_to_vec() -> borsh::to_vec()

- Add missing struct fields for v3.x:
  - RpcProgramAccountsConfig.sort_results
  - UiConfirmedBlock.num_reward_partitions
  - UiTransactionStatusMeta.cost_units
  - UiPartiallyDecodedInstruction.stack_height
  - RpcSimulateTransactionResult new optional fields

- Fix protobuf v2/v3 compatibility for hyperlane-cosmos
  (injective-protobuf requires v2)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
SPL Token 2022 v10.0 and SPL ATA v8.0 use solana_cpi::invoke which does
not support syscall stubs for offchain testing. When using processor!()
to add SPL programs, invoke calls return Ok(()) without executing.

This caused ATA's GetAccountDataSize call to Token 2022 to silently fail,
resulting in get_return_data() returning None and InvalidInstructionData.

Fix: Remove processor!()-based SPL programs and use ProgramTest's bundled
BPF programs (spl_token_2022-8.0.0.so, spl_associated_token_account-1.1.1.so)
which use proper syscalls that ProgramTest can intercept.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The e2e test runner was downloading solana-labs/solana v1.14.20 which
doesn't support Rust 2024 edition. Update to use Agave v3.0.14 which
is compatible with the SDK v3.x migration.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…na v3.x

Solana v3.x changed UpgradeableLoaderState serialization from Borsh to bincode.
- Use solana_loader_v3_interface::state::UpgradeableLoaderState with bincode::deserialize
- Handle Pubkey type conversion from solana_pubkey to solana_sdk
- Define BPF_LOADER_UPGRADEABLE_ID constant directly using pubkey! macro

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Return Box<Outbox> instead of Outbox by value in verify_account_and_fetch_inner
  (Outbox is 1118 bytes, exceeding Solana's 4KB stack limit during CPI)
- Add #[inline(never)] to AccountData::deserialize_boxed to isolate stack frames
- Add custom BorshDeserialize for IncrementalMerkle to avoid 1024-byte branch
  array stack allocation (deserialize one H256 at a time)

These changes fix "Access violation in stack frame" errors that occurred when
programs called the mailbox via CPI.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Solana SDK v3.x brings in solana-remote-wallet which depends on hidapi,
requiring libudev-dev on Linux for USB hardware wallet support.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove unused import borsh::BorshSerialize
- Fix doc comment list formatting (use - prefix)
- Allow dead_code on UpgradeableLoaderInstruction enum
- Allow needless_lifetimes on TxnBuilder impl
- Use is_some_and instead of map_or

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Resolved conflicts:
- rust/main/Cargo.toml: Keep v3.x Solana deps, drop old forked patches,
  add solana-address-lookup-table-interface
- rust/sealevel/Cargo.toml: Same as above
- Source files: Use v3.x import paths, incorporate new ALT/versioned
  transaction types from main
- Additional fixes: Update ALT imports to interface crate, fix
  system_program path, add missing RpcSimulateTransactionResult fields

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ip test

- Changed `OutboxAccount::from(*outbox)` to `OutboxAccount::from(outbox)` at 3
  call sites. The deref copied 1.1KB Outbox onto the stack before re-boxing;
  `From<Box<T>>` impl already exists and avoids the copy.
- Added Borsh serialize/deserialize roundtrip tests for IncrementalMerkle's
  custom BorshDeserialize impl (empty and non-empty trees).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…finition

Bumped solana-loader-v3-interface to 6.1.0 (compatible solana-pubkey
version) and replaced the local UpgradeableLoaderInstruction enum and
set_upgrade_authority_instruction function with the SDK's
set_upgrade_authority(). Removes ~40 lines of duplicated logic that
risked encoding drift.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replaced 18 inline `Pubkey::new_from_array(spl_noop::id().to_bytes())`
conversions with a shared `account_utils::SPL_NOOP_PROGRAM_ID` constant.
The conversion is needed because spl-noop 1.0 depends on solana-program ^2,
yielding a different Pubkey type than solana-sdk 3.0.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Deploy old core .so files (sealevel-v1.0.0 release) for sealeveltest1/2
and new locally-built .so files for sealeveltest3 to verify new agents
work with old on-chain programs. Also clean up RPC client test.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-project-automation github-project-automation bot moved this to In Review in Hyperlane Tasks Feb 17, 2026
@tkporter tkporter changed the base branch from trevor/solana-update-deps to main February 17, 2026 22:59
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@socket-security
Copy link
Copy Markdown

socket-security bot commented Feb 17, 2026

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updatedcargo/​prometheus@​0.13.4 ⏵ 0.14.079 -210093100100
Updatedcargo/​reqwest@​0.12.15 ⏵ 0.12.2879 +2010094 +1100100
Updatedcargo/​nix@​0.24.3 ⏵ 0.30.180 -191009310070
Updatedcargo/​anyhow@​1.0.87 ⏵ 1.0.1008010093100100
Updatedcargo/​thiserror@​2.0.12 ⏵ 2.0.188010093100100
Updatedcargo/​thiserror@​2.0.12 ⏵ 1.0.698110093100100
Addedcargo/​getrandom@​0.3.48110093100100
Updatedcargo/​serde@​1.0.210 ⏵ 1.0.2288110093100100
Updatedcargo/​ureq@​3.2.0 ⏵ 3.1.281 +110093100100
Addedcargo/​protobuf@​3.7.28210093100100
Updatedcargo/​blake3@​1.4.0 ⏵ 1.8.282 -2100100100100
Updatedcargo/​serde_json@​1.0.128 ⏵ 1.0.1498210093100100
Updatedcargo/​borsh@​1.5.1 ⏵ 1.6.08310093100100
Addedcargo/​futures-util@​0.3.3110010093100100
Addedcargo/​solana-sdk-ids@​2.2.110010093100100
Addedcargo/​solana-address-lookup-table-interface@​2.2.210010093100100
Addedcargo/​solana-loader-v3-interface@​3.0.010010093100100
Addedcargo/​solana-loader-v3-interface@​5.0.010010093100100
Addedcargo/​solana-program@​2.3.010010093100100
Addedcargo/​solana-system-interface@​1.0.010010093100100
Addedcargo/​solana-vote-interface@​2.2.610010093100100
Addedcargo/​solana-program@​3.0.010010093100100
Addedcargo/​solana-system-interface@​2.0.010010093100100
Addedcargo/​solana-sdk@​3.0.010010093100100
Addedcargo/​solana-commitment-config@​3.0.010010093100100
Addedcargo/​solana-vote-interface@​3.0.010010093100100
Addedcargo/​spl-discriminator@​0.5.110010093100100
Addedcargo/​spl-type-length-value@​0.9.010010093100100
Addedcargo/​spl-discriminator@​0.3.010010093100100
Addedcargo/​solana-compute-budget-interface@​3.0.010010093100100
Addedcargo/​solana-loader-v3-interface@​6.1.010010093100100
Addedcargo/​spl-noop@​1.0.010010093100100
Addedcargo/​spl-type-length-value@​0.6.010010093100100
See 28 more rows in the dashboard

View full report

tkporter and others added 10 commits February 18, 2026 13:25
sealeveltest1 (origin, NEW) -> sealeveltest2 (dest, OLD) tests new->old
sealeveltest1 (origin, NEW) -> sealeveltest3 (dest, NEW) tests new->new

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use Keypair::try_from on full 64-byte slice instead of extracting only
the 32-byte secret key. This preserves the secret/public key consistency
check and detects malformed or tampered keypair files.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Inserts 100 leaves to exercise multiple branch levels in the custom
BorshDeserialize loop.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
tkporter and others added 3 commits February 19, 2026 13:35
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Collaborator

@paulbalaji paulbalaji left a comment

Choose a reason for hiding this comment

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

Inline nit on test error message formatting.

let block = client
.get_block(slot)
.await
.expect("failed to parse block at slot {slot}");
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.

Nit: this message won’t interpolate slot because it’s a plain string literal. expect(&format!("failed to parse block at slot {slot}")) (or removing the placeholder) will give clearer failure output.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

btw I'm not planning to merge this, I'm just trying to run one-off e2e tests to ensure compatibility

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.

ah ok ez, might still be worth merging either way so we can test any future updates?

tkporter and others added 3 commits February 20, 2026 11:48
…hyperlane-monorepo into trevor/solana-update-deps-tests
…multisig ISM

Tests old mailbox + new ISM backward compatibility.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…veltest3

Added per-chain old/new warp route program selection to test backward
compatibility. sealeveltest1 and sealeveltest3 deploy old warp route
programs (from sealevel-v1.0.0) while sealeveltest2 uses new ones.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@hyper-gonk
Copy link
Copy Markdown
Contributor

hyper-gonk bot commented Feb 20, 2026

🦀 Rust Agent Docker Image Built Successfully

Service Tag
agent c1afd46-20260220-180825
Full image paths
gcr.io/abacus-labs-dev/hyperlane-agent:c1afd46-20260220-180825

@tkporter
Copy link
Copy Markdown
Member Author

tkporter commented Mar 5, 2026

closing as I just created this for some one-off tests for the big program version migration

@tkporter tkporter closed this Mar 5, 2026
@github-project-automation github-project-automation bot moved this from In Review to Done in Hyperlane Tasks Mar 5, 2026
@codecov
Copy link
Copy Markdown

codecov bot commented Mar 5, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 77.02%. Comparing base (ccd638d) to head (c1afd46).
⚠️ Report is 134 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #8135   +/-   ##
=======================================
  Coverage   77.02%   77.02%           
=======================================
  Files         117      117           
  Lines        2651     2651           
  Branches      244      244           
=======================================
  Hits         2042     2042           
  Misses        593      593           
  Partials       16       16           
Components Coverage Δ
core 87.80% <ø> (ø)
hooks 71.86% <ø> (ø)
isms 81.10% <ø> (ø)
token 86.67% <ø> (ø)
middlewares 84.98% <ø> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants