Skip to content

chore: ensure all sensible combinations of features work#217

Merged
snawaz merged 7 commits into
mainfrom
snawaz/features-combination
May 14, 2026
Merged

chore: ensure all sensible combinations of features work#217
snawaz merged 7 commits into
mainfrom
snawaz/features-combination

Conversation

@snawaz

@snawaz snawaz commented May 14, 2026

Copy link
Copy Markdown
Contributor
  • Turned out that anchor-syn 1.0 depends on syn 1.0, which is quite old and does not understand newer Rust syntax such as const {} blocks. As a result, I had to remove them from as_modern.rs (which unfortunately turns those assertions from compile-time asserts into runtime asserts 😞 ).
  • Made changes such that 30 out of 32 sensible feature combinations now build successfully. See sdk/scripts/test-combinations.sh, which is now also executed by CI.
    • The remaining 2 combinations fail when anchor-debug feature is enabled. This appears to be an anchor-lang 0.32.0 issue when that feature is enabled. Since it is not a particularly important feature (and any user of anchor 0.32 will face this problem anyway), this is acceptable for now.
Screen.Recording.2026-05-14.at.11.21.45.AM.mov

Summary by CodeRabbit

  • Refactor

    • Reorganized internal feature flag definitions for better modularity.
    • Streamlined serialization configuration for core data structures.
    • Consolidated PDA helper imports to improve code organization.
  • Chores

    • Added automated testing across multiple feature combinations to ensure compatibility.

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 14, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 7f1f75bc-bc8c-48a4-bc4c-e55feab9cca8

📥 Commits

Reviewing files that changed from the base of the PR and between b829cc7 and 0ec2c3f.

📒 Files selected for processing (12)
  • .github/workflows/build.yml
  • rust/sdk/scripts/test-combinations.sh
  • rust/sdk/src/spl/builders/delegate_ephemeral_ata.rs
  • rust/sdk/src/spl/builders/delegate_ephemeral_ata_permission.rs
  • rust/sdk/src/spl/builders/delegate_shuttle_ephemeral_ata.rs
  • rust/sdk/src/spl/builders/delegate_transfer_queue.rs
  • rust/sdk/src/spl/builders/deposit_and_delegate_shuttle_ephemeral_ata_with_merge_and_private_transfer.rs
  • rust/sdk/src/spl/builders/lamports_delegated_transfer.rs
  • rust/sdk/src/spl/builders/process_pending_transfer_queue_refill.rs
  • rust/sdk/src/spl/builders/setup_and_delegate_shuttle_ephemeral_ata_with_merge.rs
  • rust/sdk/src/spl/builders/withdraw_through_delegated_shuttle_with_merge.rs
  • rust/sdk/src/spl/mod.rs
💤 Files with no reviewable changes (1)
  • rust/sdk/src/spl/mod.rs

📝 Walkthrough

Walkthrough

This pull request refactors the SDK's feature flag organization in Cargo.toml by redefining anchor-debug to propagate to downstream crates, removing disable-realloc, and restructuring the internal features section. Serialization attributes in access control structs are updated to route Borsh serialization through crate::compat::borsh when both anchor-support and backward-compat features are absent. The layout compatibility checks in compat/as_modern.rs are moved from compile-time to runtime. Multiple SPL builder modules are updated to import PDA helpers from the consolidated crate::pda module instead of crate::spl::compat_pda, which is then removed. A new bash script for testing feature combinations is added along with a CI workflow step that executes this script.

Suggested reviewers

  • GabrielePicco
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch snawaz/features-combination

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

snawaz commented May 14, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@rust/sdk/Cargo.toml`:
- Line 31: Replace the current hard dependency entries that force-enable Anchor
when debug is set—specifically the anchor-debug feature and the symmetric
anchor-compat-debug feature—so they use Cargo's weak-dep "?/" syntax; update the
feature definitions referencing "anchor-lang-current/anchor-debug" and
"anchor-lang-compat/anchor-compat-debug" to use
"?/anchor-lang-current/anchor-debug" and
"?/anchor-lang-compat/anchor-compat-debug" respectively, ensuring the debug
feature is a no-op unless the parent anchor or anchor-compat feature is also
enabled.

In `@rust/sdk/src/access_control/structs/member.rs`:
- Around line 10-12: Remove the stale commented cfg attribute present above the
unconditional import of borsh; specifically delete the dead comment
"//#[cfg(feature = "anchor-support")]" that precedes "use crate::compat::borsh;"
in member.rs and make the same cleanup in permission.rs and undelegate_args.rs
so the intent (unconditional import with #[allow(unused_imports)]) is clear; no
other changes needed to the use statements or attributes.

In `@rust/sdk/src/compat/as_modern.rs`:
- Around line 24-31: The runtime assert! checks comparing layout of
backward_compat::AccountInfo<'static> and
solana_program::account_info::AccountInfo<'static> should be replaced with
compile-time assertions to avoid panics and runtime overhead before the
subsequent unsafe transmutation of those types; restore the previous const {
assert!(...) } pattern or use a compile-time helper such as
static_assertions::const_assert_eq! for size and align checks on
backward_compat::AccountInfo and solana_program::account_info::AccountInfo, and
if a true compile-time check is impossible due to feature-flag constraints,
replace assert! with debug_assert_eq! and add a comment documenting the
limitation and why debug-only checks are acceptable for the unsafe transmute.

In `@rust/sdk/test-combinations.sh`:
- Around line 1-4: The script can run from any CWD so add a directory-change at
the top of rust/sdk/test-combinations.sh to anchor to the SDK folder; after the
shebang (or immediately after set -euo pipefail) call cd "$(dirname "$0")" ||
exit 1 (or equivalent) so subsequent cargo build invocations run against the
rust/sdk Cargo.toml; modify test-combinations.sh to include that single-line cd
guard.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 108c6b94-73d2-45ff-a2b9-521715436f9b

📥 Commits

Reviewing files that changed from the base of the PR and between c1fc7e5 and b829cc7.

⛔ Files ignored due to path filters (1)
  • rust/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (6)
  • rust/sdk/Cargo.toml
  • rust/sdk/src/access_control/structs/member.rs
  • rust/sdk/src/access_control/structs/permission.rs
  • rust/sdk/src/access_control/structs/undelegate_args.rs
  • rust/sdk/src/compat/as_modern.rs
  • rust/sdk/test-combinations.sh

Comment thread rust/sdk/Cargo.toml
# anchor 1.0 support (CANNOT be combined with backward-compat)
anchor = ["anchor-modern"]
anchor-modern = ["anchor-support", "anchor-lang-current"]
anchor-debug = ["anchor-lang-current/anchor-debug"]

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.

🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Use ?/ so debug toggles don't activate the optional anchor deps on their own.

anchor-debug = ["anchor-lang-current/anchor-debug"] (and the symmetric anchor-compat-debug on line 39) currently force-enable the optional anchor-lang-current / anchor-lang-compat dependency whenever the debug feature is set, even if the user never enabled anchor / anchor-compat. That yields a half-configured build: the Anchor crate is compiled in, but anchor-support is still off, so the structs in access_control/structs/* keep deriving Borsh instead of Anchor traits. Using the weak-dep ?/ syntax keeps the debug flag a no-op unless the parent feature is also active.

♻️ Proposed change
-anchor-debug = ["anchor-lang-current/anchor-debug"]
+anchor-debug = ["anchor-lang-current?/anchor-debug"]
@@
-anchor-compat-debug = ["anchor-lang-compat/anchor-debug"]
+anchor-compat-debug = ["anchor-lang-compat?/anchor-debug"]

Worth extending test-combinations.sh with a standalone cargo build --features anchor-debug (and anchor-compat-debug) once this is in place to lock in the invariant.

Also applies to: 39-39

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@rust/sdk/Cargo.toml` at line 31, Replace the current hard dependency entries
that force-enable Anchor when debug is set—specifically the anchor-debug feature
and the symmetric anchor-compat-debug feature—so they use Cargo's weak-dep "?/"
syntax; update the feature definitions referencing
"anchor-lang-current/anchor-debug" and "anchor-lang-compat/anchor-compat-debug"
to use "?/anchor-lang-current/anchor-debug" and
"?/anchor-lang-compat/anchor-compat-debug" respectively, ensuring the debug
feature is a no-op unless the parent anchor or anchor-compat feature is also
enabled.

Comment on lines +10 to 12
//#[cfg(feature = "anchor-support")]
#[allow(unused_imports)]
use crate::compat::borsh;

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.

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Drop the stale //#[cfg(feature = "anchor-support")] comment.

The import is now intentionally unconditional with #[allow(unused_imports)], so the commented-out cfg line is dead documentation that obscures the intent. The same leftover appears in permission.rs (line 13) and undelegate_args.rs (line 8) — please clean up all three.

♻️ Proposed change
-//#[cfg(feature = "anchor-support")]
 #[allow(unused_imports)]
 use crate::compat::borsh;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
//#[cfg(feature = "anchor-support")]
#[allow(unused_imports)]
use crate::compat::borsh;
#[allow(unused_imports)]
use crate::compat::borsh;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@rust/sdk/src/access_control/structs/member.rs` around lines 10 - 12, Remove
the stale commented cfg attribute present above the unconditional import of
borsh; specifically delete the dead comment "//#[cfg(feature =
"anchor-support")]" that precedes "use crate::compat::borsh;" in member.rs and
make the same cleanup in permission.rs and undelegate_args.rs so the intent
(unconditional import with #[allow(unused_imports)]) is clear; no other changes
needed to the use statements or attributes.

Comment on lines +24 to +31
assert!(
core::mem::size_of::<backward_compat::AccountInfo<'static>>()
== core::mem::size_of::<solana_program::account_info::AccountInfo<'static>>()
);
assert!(
core::mem::align_of::<backward_compat::AccountInfo<'static>>()
== core::mem::align_of::<solana_program::account_info::AccountInfo<'static>>()
);

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.

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for comments or docs explaining the layout check approach
rg -i -C5 'layout|const.*assert|runtime.*check' rust/sdk/src/compat/

Repository: magicblock-labs/ephemeral-rollups-sdk

Length of output: 575


🏁 Script executed:

cat -n rust/sdk/src/compat/as_modern.rs | head -50

Repository: magicblock-labs/ephemeral-rollups-sdk

Length of output: 1784


🏁 Script executed:

# Check git history for this file to see if const blocks existed
git log --oneline -p rust/sdk/src/compat/as_modern.rs 2>/dev/null | head -100

Repository: magicblock-labs/ephemeral-rollups-sdk

Length of output: 1764


🏁 Script executed:

# Search for any documentation or PR context about layout compatibility
rg -i 'const.*block|transmut|layout.*compat' rust/sdk/src/compat/ -A3 -B3

Repository: magicblock-labs/ephemeral-rollups-sdk

Length of output: 410


🏁 Script executed:

# Search for previous layout checks or const implementations in related files
git log --all --full-history --source -- rust/sdk/src/compat/ | head -50

Repository: magicblock-labs/ephemeral-rollups-sdk

Length of output: 1481


🏁 Script executed:

# Check if backward_compat module itself has layout checks
rg 'const.*fn|size_of|align_of' rust/sdk/src/compat/backward_compat.rs -B2 -A2

Repository: magicblock-labs/ephemeral-rollups-sdk

Length of output: 160


🏁 Script executed:

# Look for any const blocks in the compat directory
fd . rust/sdk/src/compat/ -name '*.rs' -exec rg 'const\s*\{' {} +

Repository: magicblock-labs/ephemeral-rollups-sdk

Length of output: 312


🏁 Script executed:

# Check the entire git log for this specific function to see if it existed before
git log --all -S 'AsModern for backward_compat::AccountInfo' -- rust/sdk/

Repository: magicblock-labs/ephemeral-rollups-sdk

Length of output: 1609


🏁 Script executed:

# Get the specific changes to AccountInfo::as_modern between the two commits
git show f6339f8:rust/sdk/src/compat/as_modern.rs 2>/dev/null || echo "File may not have existed at f6339f8"

Repository: magicblock-labs/ephemeral-rollups-sdk

Length of output: 1521


🏁 Script executed:

# Search more broadly in older commits for AccountInfo and layout checks
git log --all -p -S 'backward_compat::AccountInfo' -- 'rust/sdk/src/compat/' | head -150

Repository: magicblock-labs/ephemeral-rollups-sdk

Length of output: 5549


🏁 Script executed:

# Check what files existed in the compat directory at the previous commit
git ls-tree -r f6339f8 -- rust/sdk/src/compat/

Repository: magicblock-labs/ephemeral-rollups-sdk

Length of output: 416


Remove runtime layout checks or provide compile-time assertions.

The layout compatibility checks were moved from compile-time (const { assert!(...) }) to runtime (assert!). This introduces a safety concern:

  1. Compile-time checks (previous version) guaranteed layout compatibility at build time with zero runtime cost and prevented miscompilation entirely.
  2. Runtime checks (current version) execute on every function call and can panic in production.

The unsafe transmutation at line 32 depends on these checks. Per coding guidelines for this file path (rust/sdk/**), panic-prone patterns require proper error handling or explicit justification.

Please clarify why the const block was removed. If feature flag constraints made it incompatible, consider whether debug_assert! (checked in debug builds but optimized away in release) would be acceptable, or if the checks can be restored.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@rust/sdk/src/compat/as_modern.rs` around lines 24 - 31, The runtime assert!
checks comparing layout of backward_compat::AccountInfo<'static> and
solana_program::account_info::AccountInfo<'static> should be replaced with
compile-time assertions to avoid panics and runtime overhead before the
subsequent unsafe transmutation of those types; restore the previous const {
assert!(...) } pattern or use a compile-time helper such as
static_assertions::const_assert_eq! for size and align checks on
backward_compat::AccountInfo and solana_program::account_info::AccountInfo, and
if a true compile-time check is impossible due to feature-flag constraints,
replace assert! with debug_assert_eq! and add a comment documenting the
limitation and why debug-only checks are acceptable for the unsafe transmute.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

const {} isn't supported by anchor-syn which depends on an older sync = 1.0 which does not understand const-block.

Comment thread rust/sdk/scripts/test-combinations.sh
@snawaz snawaz marked this pull request as ready for review May 14, 2026 05:35

snawaz commented May 14, 2026

Copy link
Copy Markdown
Contributor Author

Merge activity

  • May 14, 6:49 AM UTC: A user started a stack merge that includes this pull request via Graphite.
  • May 14, 6:49 AM UTC: @snawaz merged this pull request with Graphite.

@snawaz snawaz merged commit 649d007 into main May 14, 2026
5 checks passed
@snawaz snawaz deleted the snawaz/features-combination branch May 14, 2026 06:52
Dodecahedr0x pushed a commit that referenced this pull request May 18, 2026
- Turned out that `anchor-syn 1.0` depends on `syn 1.0`, which is quite old and does not understand newer Rust syntax such as `const {}` blocks. As a result, I had to remove them from `as_modern.rs` (which unfortunately turns those assertions from compile-time asserts into runtime asserts 😞 ).
  - Interestingly, there is [an issue created on anchor repo](otter-sec/anchor#4521) just 2 days back and [a PR that upgrades to `syn 2.0`](otter-sec/anchor#4523).
- Made changes such that **30 out of 32 sensible feature combinations** now build successfully. See `sdk/scripts/test-combinations.sh`, which is now also executed by CI.
  - The remaining 2 combinations fail when `anchor-debug` feature is enabled. This appears to be an `anchor-lang 0.32.0` issue when that feature is enabled. Since it is not a particularly important feature  (and any user of anchor 0.32 will face this problem anyway), this is acceptable for now.
  
 

https://github.com/user-attachments/assets/b51e8ab9-a81a-4a29-910c-a12a68b90b1c



<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **Refactor**
  * Reorganized internal feature flag definitions for better modularity.
  * Streamlined serialization configuration for core data structures.
  * Consolidated PDA helper imports to improve code organization.

* **Chores**
  * Added automated testing across multiple feature combinations to ensure compatibility.

<!-- review_stack_entry_start -->

[![Review Change Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/magicblock-labs/ephemeral-rollups-sdk/pull/217)

<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
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.

3 participants