-
Notifications
You must be signed in to change notification settings - Fork 97
feat: support for canister ID migration #4423
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
base: master
Are you sure you want to change the base?
Conversation
| impl fmt::Display for ValidationError { | ||
| fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
| match self { | ||
| ValidationError::MigrationsDisabled(Reserved) => { | ||
| write!(f, "Canister migrations are disabled at the moment.") | ||
| } | ||
| ValidationError::RateLimited(Reserved) => write!( | ||
| f, | ||
| "Canister migration has been rate-limited. Try again later." | ||
| ), | ||
| ValidationError::ValidationInProgress { canister } => write!( | ||
| f, | ||
| "Validation for canister {canister} is already in progress." | ||
| ), | ||
| ValidationError::MigrationInProgress { canister } => write!( | ||
| f, | ||
| "Canister migration for canister {canister} is already in progress." | ||
| ), | ||
| ValidationError::CanisterNotFound { canister } => { | ||
| write!(f, "The canister {canister} does not exist.") | ||
| } | ||
| ValidationError::SameSubnet(Reserved) => { | ||
| write!(f, "Both canisters are on the same subnet.") | ||
| } | ||
| ValidationError::CallerNotController { canister } => write!( | ||
| f, | ||
| "The canister {canister} is not controlled by the calling identity." | ||
| ), | ||
| ValidationError::NotController { canister } => write!( | ||
| f, | ||
| "The NNS canister sbzkb-zqaaa-aaaaa-aaaiq-cai is not a controller of canister {canister}." | ||
| ), | ||
| ValidationError::MigratedNotStopped(Reserved) => { | ||
| write!(f, "The migrated canister is not stopped.") | ||
| } | ||
| ValidationError::MigratedNotReady(Reserved) => write!( | ||
| f, | ||
| "The migrated canister is not ready for migration. Try again later." | ||
| ), | ||
| ValidationError::ReplacedNotStopped(Reserved) => { | ||
| write!(f, "The replaced canister is not stopped.") | ||
| } | ||
| ValidationError::ReplacedHasSnapshots(Reserved) => { | ||
| write!(f, "The replaced canister has snapshots.") | ||
| } | ||
| ValidationError::MigratedInsufficientCycles(Reserved) => write!( | ||
| f, | ||
| "The migrated canister does not have enough cycles for canister migration. Top up the migrated canister with the required amount of cycles." | ||
| ), | ||
| ValidationError::CallFailed { reason } => { | ||
| write!(f, "Internal IC error: a call failed due to {reason}") | ||
| } | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We usually do this with thiserror, e.g. like here: https://github.com/dfinity/sdk/blob/master/src/canisters/frontend/ic-asset/src/error/create_chunk.rs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the pointer! I refactored the code into using thiserror, but still wonder if the following code
let (result,): (Result<(), Option<ValidationError>>,) = canister
.update(MIGRATE_CANISTER_METHOD)
.with_arg(arg)
.build()
.await?;
match result {
Ok(()) => Ok(()),
Err(None) => Err(anyhow::anyhow!("Validation failed with an unknown error.")),
Err(Some(err)) => Err(anyhow::anyhow!("Validation failed: {err}")),
}
dealing with the ValidationError is fine or should somehow avoid the "manual" anyhow::anyhow!("Validation failed: {err}")?
Description
This PR implements support for canister ID migration in dfx: Canister ID migration can be performed using
dfx canister migrate-idand its status can be checked out usingdfx canister migration-status.How Has This Been Tested?
An end-to-end test is introduced in this PR.
Checklist: