Skip to content

fix(sns): Reduce heap memory usage in SNS governance#10223

Open
jasonz-dfinity wants to merge 1 commit into
masterfrom
reduce-heap-memory-usage-in-sns-governance
Open

fix(sns): Reduce heap memory usage in SNS governance#10223
jasonz-dfinity wants to merge 1 commit into
masterfrom
reduce-heap-memory-usage-in-sns-governance

Conversation

@jasonz-dfinity
Copy link
Copy Markdown
Contributor

@jasonz-dfinity jasonz-dfinity commented May 13, 2026

Summary

Two adjustments to optimize SNS governance heap usage.

Free ballot capacity after reward distribution

Once a proposal reward round is complete, the proposal ballots map is jettisoned — but BTreeMap::clear() only removes entries while keeping the underlying capacity allocated, so the memory was not actually released. Replacing the field with BTreeMap::new() deallocates the backing storage.

Broaden check_heap_can_grow coverage

check_heap_can_grow is now enforced in more places, so the canister rejects new allocations earlier when it is close to its heap limit:

  1. Every manage_neuron command except MakeProposal and RegisterVote. These two must stay available so the SNS can vote on a recovery proposal even when heap is tight.
  2. claim_swap_neurons, mirroring the check that used to live in add_neuron.
  3. Non-emergency proposal validation, including the new AdvanceSnsTargetVersion action (successor of UpgradeSnsToNextVersion).

The check is removed from add_neuron and split_neuron because both are now covered transitively: split_neuron is only called from manage_neuron, and add_neuron is only called from split_neuron, claim_neuron (also under manage_neuron), and claim_swap_neurons (covered directly).

NNS1-4195. Free ballot capacity after reward distribution (BTreeMap::clear
leaves it allocated), and extend check_heap_can_grow to all non-emergency
manage_neuron commands, claim_swap_neurons, and proposal validation.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added the fix label May 13, 2026
@jasonz-dfinity jasonz-dfinity requested a review from Copilot May 13, 2026 16:59
@jasonz-dfinity jasonz-dfinity marked this pull request as ready for review May 13, 2026 16:59
@jasonz-dfinity jasonz-dfinity requested a review from a team as a code owner May 13, 2026 16:59
Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

This pull request changes code owned by the Governance team. Therefore, make sure that
you have considered the following (for Governance-owned code):

  1. Update unreleased_changelog.md (if there are behavior changes, even if they are
    non-breaking).

  2. Are there BREAKING changes?

  3. Is a data migration needed?

  4. Security review?

How to Satisfy This Automatic Review

  1. Go to the bottom of the pull request page.

  2. Look for where it says this bot is requesting changes.

  3. Click the three dots to the right.

  4. Select "Dismiss review".

  5. In the text entry box, respond to each of the numbered items in the previous
    section, declare one of the following:

  • Done.

  • $REASON_WHY_NO_NEED. E.g. for unreleased_changelog.md, "No
    canister behavior changes.", or for item 2, "Existing APIs
    behave as before.".

Brief Guide to "Externally Visible" Changes

"Externally visible behavior change" is very often due to some NEW canister API.

Changes to EXISTING APIs are more likely to be "breaking".

If these changes are breaking, make sure that clients know how to migrate, how to
maintain their continuity of operations.

If your changes are behind a feature flag, then, do NOT add entrie(s) to
unreleased_changelog.md in this PR! But rather, add entrie(s) later, in the PR
that enables these changes in production.

Reference(s)

For a more comprehensive checklist, see here.

GOVERNANCE_CHECKLIST_REMINDER_DEDUP

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR reduces SNS governance heap pressure by freeing proposal ballot storage after reward settlement and broadening low-heap rejection paths for memory-growing operations.

Changes:

  • Replaces cleared proposal ballot maps with new BTreeMaps to release allocated capacity.
  • Adds low-resource allowlist helpers for manage-neuron commands and proposal actions.
  • Moves heap-growth checks toward manage_neuron, claim_swap_neurons, and proposal validation paths.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
rs/sns/governance/unreleased_changelog.md Documents the heap memory optimization changes.
rs/sns/governance/src/types.rs Adds low-resource allowlist logic for manage-neuron commands and AdvanceSnsTargetVersion.
rs/sns/governance/src/governance.rs Adjusts heap checks and releases proposal ballot backing storage after rewards.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +4436 to +4443
if let Err(err) = self.check_heap_can_grow() {
log!(
ERROR,
"Could not claim_swap_neurons due to heap growth limits. Err: {}",
err.error_message,
);
return ClaimSwapNeuronsResponse::new_with_error(ClaimSwapNeuronsError::Internal);
}
Comment on lines +4798 to +4800
if !command.allowed_when_resources_are_low() {
self.check_heap_can_grow()?;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants