Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: a new install_code mode #135

Merged
merged 25 commits into from
Sep 13, 2023
Merged

feat: a new install_code mode #135

merged 25 commits into from
Sep 13, 2023

Conversation

roman-kashitsyn
Copy link
Contributor

@roman-kashitsyn roman-kashitsyn commented Feb 2, 2023

This PR describes a new variant of the upgrade mode for install_code that allows canister controllers to skip the pre_upgrade hook during the upgrade.

This upgrade method can serve two purposes.

  1. Act as an escape hatch if the canister entered otherwise irrecoverable state due to a critical bug in the post_upgrade method of the new canister module. The stable memory must already contain the entire state for the "fix" to work.

  2. Canister developers can use it during canister deployment to excercise the pre_upgrade method of the new canister.

Recovering from buggy post_upgrade hooks

Imagine that the post_upgrade method implementation has a bug that bricks the canister. Upgrading the canister in such a state is either impossible (pre_upgrade method traps unconditionally) or can result in a data loss (the post_upgrade method erroneously discarded important data, and executing pre_upgrade would corrupt the original). The stable memory, however, might still contain the correct state that the old module recorded.

If developers ever find themselves in such situation (I did), the upgrade install method with skip_pre_upgrade is the only salvation.

Testing the pre_upgrade hook

Testing pre_upgrade hooks is a constant source of struggle. If this method contains a bug, the canister can become unupgradable.

The upgrade method with skip_pre_upgrade provides a method to excercise the pre_upgrade method of the new canister module without the fear of data loss using the following procedure:

  1. Stop the canister.
  2. Upgrade the canister to the new module.
  3. If upgrade succeeded, upgrade the canister again to the same module. This upgrade will excercise the pre_upgrade hook.
  4. If the second upgrade succeeds, proceed with the next step. Otherwise, install the old canister module in upgrade mode with skip_pre_upgrade.
  5. Start the canister.

This change describes a new install_code mode that allows canister
controllers to skip the pre_upgrade hook during the upgrade.

This upgrade method can serve two purposes.

  1. Act as an escape hatch if the canister entered otherwise
     irrecoverable state due to a critical bug in the `post_upgrade`
     method of the new canister version. The stable memory must already
     contain the entire state for the "fix" to work.

  2. Canister developers can use it during canister deployment to
     excercise the `pre_upgrade` method of the new canister.

Imagine that the `post_upgrade` method implementation has a bug that
bricks the canister. Upgrading the canister in such a state is either
impossible (`pre_upgrade` method traps unconditionally) or can result
in a data loss (the `post_upgrade` method erronously discarded
important data, and executing `pre_upgrade` would corrupt the
original).  The stable memory, however, might still contain the
correct state that the old version recorded.

If developers ever find themselves in such situation (I did), the
`evict` install method is the only salvation.

Testing `pre_upgrade` hooks is a constant source of struggle.
If this method contains a bug, the canister can become unupgradable.

The evict method provides a method to excercise the `pre_upgrade`
method of the new canister version without the fear of data loss using
the following procedure:

  1. Stop the canister.
  2. Upgrade the canister to the new version.
  3. If upgrade succeeded, upgrade the canister again to same version.
     This upgrade will excercise the `pre_upgrade` hook.
  4. If the second upgrade succeeds, proceed with the next step.
     Otherwise, install the old version of the canister in `evict` mode.
  5. Start the canister.
@roman-kashitsyn roman-kashitsyn requested a review from a team as a code owner February 2, 2023 21:41
@netlify
Copy link

netlify bot commented Feb 2, 2023

Deploy Preview for ic-interface-spec ready!

Name Link
🔨 Latest commit 211c3f2
🔍 Latest deploy log https://app.netlify.com/sites/ic-interface-spec/deploys/64c2487d23b06e0008c7fe09
😎 Deploy Preview https://deploy-preview-135--ic-interface-spec.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

spec/index.adoc Outdated Show resolved Hide resolved
spec/index.adoc Outdated Show resolved Hide resolved
Dfinity-Bjoern

This comment was marked as outdated.

@Dfinity-Bjoern

This comment was marked as outdated.

spec/ic.did Outdated Show resolved Hide resolved
spec/index.md Outdated Show resolved Hide resolved
spec/index.md Outdated Show resolved Hide resolved
spec/index.md Outdated Show resolved Hide resolved
spec/index.md Outdated Show resolved Hide resolved
spec/index.md Outdated Show resolved Hide resolved
spec/index.md Outdated Show resolved Hide resolved
crusso

This comment was marked as outdated.

@crusso

This comment was marked as off-topic.

mraszyk and others added 2 commits July 26, 2023 16:22
Co-authored-by: Claudio Russo <[email protected]>
Co-authored-by: Claudio Russo <[email protected]>
spec/index.md Outdated Show resolved Hide resolved
@oggy-dfin

This comment was marked as resolved.

@mraszyk

This comment was marked as resolved.

@Dfinity-Bjoern

This comment was marked as outdated.

@roman-kashitsyn

This comment was marked as resolved.

@crusso

This comment was marked as resolved.

@roman-kashitsyn

This comment was marked as resolved.

@crusso

This comment was marked as resolved.

@mraszyk

This comment was marked as resolved.

@Dfinity-Bjoern

This comment was marked as resolved.

@netlify
Copy link

netlify bot commented Aug 16, 2023

Deploy Preview for ic-interface-spec ready!

Name Link
🔨 Latest commit 7ae270e
🔍 Latest deploy log https://app.netlify.com/sites/ic-interface-spec/deploys/64dcdefb765eea0008af839b
😎 Deploy Preview https://deploy-preview-135--ic-interface-spec.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@mraszyk

This comment was marked as resolved.

gitlab-dfinity pushed a commit to dfinity/ic that referenced this pull request Aug 28, 2023
…upgrade-flag' into 'master'

feat: EXC-1422: Canister install mode v2 with skip pre-upgrade flag

This MR is the first step that follows dfinity/interface-spec#135.
Closes EXC-1422. 

Closes EXC-1422

See merge request dfinity-lab/public/ic!13842
gitlab-dfinity pushed a commit to dfinity/ic that referenced this pull request Sep 13, 2023
…-v-2-in-order-to-use-skip-upgrade-functionality' into 'master'

feat: Allow replica to receive CanisterInstallModeV2 to use skip_upgrade functionality

This MR enables canisters to receive CanisterInstallModeV2, hence it enables `skip_pre_upgrade` functionality. This should be included in the release after the next one. It is the last step for [feature](https://dfinity.atlassian.net/browse/EXC-1334) initiated by interface [specs](dfinity/interface-spec#135).
Closes EXC-1474 

Closes EXC-1474

See merge request dfinity-lab/public/ic!14479
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.

9 participants