Steward: Fix Rebalance try_accounts stack frame exceeding SBF limit - #316
Draft
aoikurokawa wants to merge 1 commit into
Draft
Steward: Fix Rebalance try_accounts stack frame exceeding SBF limit#316aoikurokawa wants to merge 1 commit into
aoikurokawa wants to merge 1 commit into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Rebalance::try_accounts(the anchor-generated account validation for theRebalanceinstruction) has a 4,144-byte stack frame — 48 bytes over the SBF per-function limit of 4,096. Every build has been printing this as a non-fatal diagnostic:With the current toolsuite (anza v3.0.8) the overflow happens to be harmless — codegen luck. Building the unchanged master source with newer platform-tools (v1.52, via the anza v3.1.9 toolsuite) shifts the stack layout so the same overflow corrupts a pointer, and
Rebalancefails deterministically at runtime:All 7
steward::test_cycle::*integration tests that reachRebalancefail this way. This was discovered while attempting the solana-gossip upgrade (which forces a toolsuite bump for edition-2024 dependencies), but it's independent of that work: any future toolchain upgrade of the program build pipeline produces a brokenRebalanceuntil this is fixed.Root cause
Three
#[account(...)]constraints calldeserialize_stake_pool(&stake_pool)?.<field>. The helper returnsStakePoolby value, so each call materializes the full struct (~600B) intry_accounts' own frame — by-value returns land in the caller's frame, so the helper being a separate function doesn't help.Fix
The SBF stack limit is per-function-frame, so the fix moves the temporaries into their own frames: three
#[inline(never)]accessors instake_pool_utils.rsthat deserialize internally and return only the needed field (u8/Pubkey):bump = deserialize_stake_pool(&stake_pool)?.stake_withdraw_bump_seed→bump = stake_pool_withdraw_bump_seed(&stake_pool)?address = ...validator_list→address = stake_pool_validator_list(&stake_pool)?address = ...reserve_stake→address = stake_pool_reserve_stake(&stake_pool)?Identical checks, identical error propagation, no behavior change. Two files, no IDL change, no Cargo.lock change.