Skip to content

refactor(nns): consolidate deterministic subaccount validation in NeuronStore#9186

Open
jasonz-dfinity wants to merge 4 commits intojason/refactor-neuron-subaccount-generationfrom
jason/refactor-deterministic-subaccount-validation
Open

refactor(nns): consolidate deterministic subaccount validation in NeuronStore#9186
jasonz-dfinity wants to merge 4 commits intojason/refactor-neuron-subaccount-generationfrom
jason/refactor-deterministic-subaccount-validation

Conversation

@jasonz-dfinity
Copy link
Copy Markdown
Contributor

@jasonz-dfinity jasonz-dfinity commented Mar 4, 2026

Why

The "compute deterministic subaccount → check collision → return PreconditionFailed" pattern was duplicated across split_neuron, spawn_neuron, and disburse_to_neuron with identical error handling.

What

  • Add NeuronStore::ensure_subaccount_available() which checks that a caller-supplied subaccount is not already in use
  • Replace the three inline collision-check blocks with calls to the new method
  • Make has_neuron_with_subaccount private since all external callers now use either new_neuron_subaccount (random) or ensure_subaccount_available (deterministic)

PR Chain

Testing

  • Added unit tests for ensure_subaccount_available: success path and collision error path

Add NeuronStore::validate_deterministic_subaccount() which checks that a
caller-supplied subaccount is not already in use, replacing the repeated
has_neuron_with_subaccount + GovernanceError pattern in split_neuron,
spawn_neuron, and disburse_to_neuron.

has_neuron_with_subaccount is now private to NeuronStore since all
external callers use either new_neuron_subaccount (random) or
validate_deterministic_subaccount (deterministic).
@jasonz-dfinity jasonz-dfinity requested a review from a team as a code owner March 4, 2026 18:47
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

- Rename validate_deterministic_subaccount to ensure_subaccount_available
- Remove unnecessary shadowing in disburse_to_neuron
- Add unit tests for ensure_subaccount_available success and collision paths
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 consolidates deterministic (caller-supplied) neuron subaccount collision validation into NeuronStore, removing duplicated “compute → check collision → precondition-failed” logic across multiple Governance operations.

Changes:

  • Introduces NeuronStore::ensure_subaccount_available() and a dedicated NeuronStoreError::SubaccountAlreadyExists.
  • Replaces inline deterministic subaccount collision checks in split_neuron, spawn_neuron, and disburse_to_neuron with the new helper.
  • Makes has_neuron_with_subaccount private and adds unit tests for the new helper.

Reviewed changes

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

File Description
rs/nns/governance/src/neuron_store.rs Adds the consolidated deterministic subaccount availability check, error variant/display, and error mapping to GovernanceError.
rs/nns/governance/src/governance.rs Switches deterministic subaccount paths in split/spawn/disburse-to-neuron to use ensure_subaccount_available.
rs/nns/governance/src/neuron_store/neuron_store_tests.rs Adds unit tests covering success and collision error paths for ensure_subaccount_available.

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

…-generation' into jason/refactor-deterministic-subaccount-validation

# Conflicts:
#	rs/nns/governance/src/neuron_store/neuron_store_tests.rs
@jasonz-dfinity jasonz-dfinity dismissed github-actions[bot]’s stale review May 5, 2026 22:40
  1. No canister behavior changes -- pure internal refactor consolidating an existing collision check.
  2. Existing APIs behave as before.
  3. No data migration needed.
  4. No security-sensitive changes -- refactor preserves the existing collision check logic.
@jasonz-dfinity jasonz-dfinity requested a review from Copilot May 5, 2026 22:45
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

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.


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

Comment thread rs/nns/governance/src/neuron_store.rs Outdated
NeuronStoreError::SubaccountAlreadyExists { subaccount } => {
write!(
f,
"There is already a neuron with subaccount {subaccount:?}."
Add underscore separators to integer literal suffixes (5 occurrences) to
satisfy clippy::unseparated_literal_suffix, and switch the
SubaccountAlreadyExists Display impl to use Subaccount's hex Display
instead of Debug for a more readable user-facing error.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants