Skip to content

fix(release): correctly generate and apply engine-controller upgrade proposals#10458

Open
pietrodimarco-dfinity wants to merge 2 commits into
masterfrom
pietrodimarco/engine-controller-upgrade-arg
Open

fix(release): correctly generate and apply engine-controller upgrade proposals#10458
pietrodimarco-dfinity wants to merge 2 commits into
masterfrom
pietrodimarco/engine-controller-upgrade-arg

Conversation

@pietrodimarco-dfinity

@pietrodimarco-dfinity pietrodimarco-dfinity commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Two fixes so the NNS release tooling handles the engine-controller canister
correctly end-to-end. (Follow-up to #10399, which added partial support.)

1. Map engine-controller to its source location (functions.sh)

get_nns_canister_code_location had no code_location__engine_controller
entry, so generating an engine-controller upgrade proposal aborted under
set -u with an unbound-variable error on the ${!n} indirect lookup:

.../lib/functions.sh: line 163: !n: unbound variable

Added the mapping to rs/engine_controller so proposal-text generation (and
the unreleased_changelog.md lookup) resolves.

2. Pass () upgrade arg for engine-controller (release-runscript)

The canister's post_upgrade takes Option<EngineControllerInitArgs>:

#[post_upgrade]
fn post_upgrade(args: Option<EngineControllerInitArgs>) { apply_init_args(args); }

An upgrade proposal generated without an argument carries an empty install
arg, which Candid cannot decode (no DIDL header), so post_upgrade traps and
the upgrade rolls back. Because NNS root's change_nns_canister is
fire-and-forget (it spawns stop→install→start and replies immediately), the
proposal is still recorded as Executed with no failure_reason — the
canister is silently never upgraded.

Generate engine-controller proposals with an explicit () arg (the same
mechanism already used for cycles-minting) so post_upgrade decodes to
None and the upgrade applies.

Verification

Reproduced on a testnet:

  • No-arg upgrade proposal → status = Executed, but module hash and embedded
    git_commit_id unchanged (silent no-op).
  • Identical upgrade with explicit () arg → module hash and git_commit_id
    updated to the target commit.
  • cargo check -p release-runscript passes.

…roposals

The engine-controller canister's `post_upgrade` takes
`Option<EngineControllerInitArgs>` and traps when Candid-decoding an empty
argument (no `DIDL` header). Upgrade proposals generated without an explicit
argument therefore carry an empty arg, so on execution the install rolls
back inside NNS root's fire-and-forget `change_nns_canister` while the
proposal still reports as `Executed` -- the canister is silently never
upgraded.

Generate engine-controller upgrade proposals with an explicit `()` arg (the
same mechanism already used for cycles-minting) so `post_upgrade` decodes to
`None` and the upgrade actually applies.
@pietrodimarco-dfinity pietrodimarco-dfinity requested a review from a team as a code owner June 13, 2026 07:20
@github-actions github-actions Bot added the fix label Jun 13, 2026

@github-actions github-actions 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.

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

@zeropath-ai

zeropath-ai Bot commented Jun 13, 2026

Copy link
Copy Markdown

No security or compliance issues detected. Reviewed everything up to 6494992.

Security Overview
Detected Code Changes
Change Type Relevant files
Refactor ► rs/nervous_system/tools/release-runscript/src/main.rs
    Handle upgrade arguments for cycles-minting and engine-controller canisters
Enhancement ► rs/nervous_system/tools/release/lib/functions.sh
    Add code location for engine-controller canister

`get_nns_canister_code_location` lacked a `code_location__engine_controller`
entry, so generating an engine-controller upgrade proposal failed under
`set -u` with an unbound-variable error on the `${!n}` indirect lookup.

Add the mapping to `rs/engine_controller` so proposal-text generation (and the
unreleased_changelog lookup) resolves correctly.
@pietrodimarco-dfinity pietrodimarco-dfinity changed the title fix(release-runscript): pass '()' upgrade arg for engine-controller proposals fix(release): correctly generate and apply engine-controller upgrade proposals Jun 13, 2026
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