pub(crate) fn delete_canister(
        &self,
        sender: PrincipalId,
        canister_id_to_delete: CanisterId,
        state: &mut ReplicatedState,
    ) -> Result<(), CanisterManagerError> {
        if let Ok(canister_id) = CanisterId::try_from(sender) {
            if canister_id == canister_id_to_delete {
                // A canister cannot delete itself.
                return Err(CanisterManagerError::DeleteCanisterSelf(canister_id));
            }
        }

        let canister_to_delete = self.validate_canister_exists(state, canister_id_to_delete)?;

        // Validate the request is from the controller.
        self.validate_controller(canister_to_delete, &sender)?;

        self.validate_canister_is_stopped(canister_to_delete)?;

        // Once a canister is stopped, it stops accepting new messages, so this should
        // never happen.
        if canister_to_delete.has_input() {
            fatal!(
                self.log,
                "[EXC-BUG] Trying to delete canister {} while having messages in its input queue.",
                canister_to_delete.canister_id()
            );
        }

        // This scenario should be impossible because:
        //
        // 1) A stopped canister does not accept new messages.
        //
        // 2) A canister is transitioned to a stopped state at the end of a round.
        //
        // 3) All output messages are cleared by the `StreamBuilder` at the end of
        //    every round.
        //
        // Because the canister is already stopped, it must have been stopped in a
        // previous round (2), had its output queued emptied in a previous round (3),
        // and the output queue is still empty because it didn't accept any new
        // messages (1).
        if canister_to_delete.has_output() {
            fatal!(
                self.log,
                "[EXC-BUG] Trying to delete canister {} while having messages in its output queue.",
                canister_to_delete.canister_id()
            );
        }

        // When a canister is deleted:
        // - its state is permanently deleted, and
        // - its cycles are discarded.

        // Take out the canister from `ReplicatedState`.
        let _canister_to_delete = state.take_canister_state(&canister_id_to_delete).unwrap();

        let layout = canister_layout(state.path(), &canister_id_to_delete);
        layout
            .mark_deleted()
            .expect("failed to mark canister as deleted on the filesystem");

        // The canister has now been removed from `ReplicatedState` and is dropped
        // once the function is out of scope.
        Ok(())
    }
/// Permanently deletes a canister from `ReplicatedState`.
///
/// The canister must be `Stopped` and only the controller of the canister
/// can delete it. The controller must be a canister and the canister
/// cannot be its own controller.
///
/// Any remaining cycles in the canister are discarded.
///
/// #Errors
/// CanisterManagerError::DeleteCanisterSelf is the canister attempts to
/// delete itself.
Permanently deletes a canister from `ReplicatedState`.
The canister must be `Stopped` and only the controller of the canister
can delete it. The controller must be a canister and the canister
cannot be its own controller.

Any remaining cycles in the canister are discarded.
Permanently deletes a canister from ` ReplicatedState ` . The canister must be ` Stopped ` and only the controller of the canister can delete it . The controller must be a canister and the canister cannot be its own controller . Any remaining cycles in the canister are discarded .
pub(crate) fn delete_canister(
        &self,
        sender: PrincipalId,
        canister_id_to_delete: CanisterId,
        state: &mut ReplicatedState,
    ) -> Result<(), CanisterManagerError> {
        if let Ok(canister_id) = CanisterId::try_from(sender) {
            if canister_id == canister_id_to_delete {
                // A canister cannot delete itself.
                return Err(CanisterManagerError::DeleteCanisterSelf(canister_id));
            }
        }
        let canister_to_delete = self.validate_canister_exists(state, canister_id_to_delete)?;
        // Validate the request is from the controller.
        self.validate_controller(canister_to_delete, &sender)?;
        self.validate_canister_is_stopped(canister_to_delete)?;
        // Once a canister is stopped, it stops accepting new messages, so this should
        // never happen.
        if canister_to_delete.has_input() {
            fatal!(
                self.log,
                "[EXC-BUG] Trying to delete canister {} while having messages in its input queue.",
                canister_to_delete.canister_id()
            );
        }
        // This scenario should be impossible because:
        //
        // 1) A stopped canister does not accept new messages.
        //
        // 2) A canister is transitioned to a stopped state at the end of a round.
        //
        // 3) All output messages are cleared by the `StreamBuilder` at the end of
        //    every round.
        //
        // Because the canister is already stopped, it must have been stopped in a
        // previous round (2), had its output queued emptied in a previous round (3),
        // and the output queue is still empty because it didn't accept any new
        // messages (1).
        if canister_to_delete.has_output() {
            fatal!(
                self.log,
                "[EXC-BUG] Trying to delete canister {} while having messages in its output queue.",
                canister_to_delete.canister_id()
            );
        }
        // When a canister is deleted:
        // - its state is permanently deleted, and
        // - its cycles are discarded.
        // Take out the canister from `ReplicatedState`.
        let _canister_to_delete = state.take_canister_state(&canister_id_to_delete).unwrap();
        let layout = canister_layout(state.path(), &canister_id_to_delete);
        layout
            .mark_deleted()
            .expect("failed to mark canister as deleted on the filesystem");
        // The canister has now been removed from `ReplicatedState` and is dropped
        // once the function is out of scope.
        Ok(())
    }
pub ( crate ) fn delete_canister ( & self , sender : PrincipalId , canister_id_to_delete : CanisterId , state : & mut ReplicatedState , ) -> Result < ( ) , CanisterManagerError > { if let Ok ( canister_id ) = CanisterId :: try_from ( sender ) { if canister_id == canister_id_to_delete { // A canister cannot delete itself. return Err ( CanisterManagerError :: DeleteCanisterSelf ( canister_id ) ) ; } } let canister_to_delete = self . validate_canister_exists ( state , canister_id_to_delete ) ? ; // Validate the request is from the controller. self . validate_controller ( canister_to_delete , & sender ) ? ; self . validate_canister_is_stopped ( canister_to_delete ) ? ; // Once a canister is stopped, it stops accepting new messages, so this should // never happen. if canister_to_delete . has_input ( ) { fatal ! ( self log " " canister_to_delete canister_id ( ) ) ; } // This scenario should be impossible because: // // 1) A stopped canister does not accept new messages. // // 2) A canister is transitioned to a stopped state at the end of a round. // // 3) All output messages are cleared by the `StreamBuilder` at the end of //    every round. // // Because the canister is already stopped, it must have been stopped in a // previous round (2), had its output queued emptied in a previous round (3), // and the output queue is still empty because it didn't accept any new // messages (1). if canister_to_delete . has_output ( ) { fatal ! ( self log " " canister_to_delete canister_id ( ) ) ; } // When a canister is deleted: // - its state is permanently deleted, and // - its cycles are discarded. // Take out the canister from `ReplicatedState`. let _canister_to_delete = state . take_canister_state ( & canister_id_to_delete ) . unwrap ( ) ; let layout = canister_layout ( state . path ( ) , & canister_id_to_delete ) ; layout . mark_deleted ( ) . expect ( " " ) ; // The canister has now been removed from `ReplicatedState` and is dropped // once the function is out of scope. Ok ( ( ) ) }
Permanently deletes a canister from `ReplicatedState`.
Permanently deletes a canister from ` ReplicatedState ` .
&self
sender
PrincipalId
canister_id_to_delete
CanisterId
state
&mut ReplicatedState
&self
sender
PrincipalId
canister_id_to_delete
CanisterId
state
&mut ReplicatedState
errors
:DeleteCanisterSelf is the canister attempts to
delete itself.
: DeleteCanisterSelf is the canister attempts to delete itself .