pub(crate) fn should_accept_ingress_message(
        &self,
        state: Arc<ReplicatedState>,
        provisional_whitelist: &ProvisionalWhitelist,
        sender: UserId,
        method_name: &str,
        payload: &[u8],
    ) -> Result<(), CanonicalError> {
        fn is_sender_controller(
            canister_id: CanisterId,
            sender: UserId,
            state: Arc<ReplicatedState>,
        ) -> Result<(), CanonicalError> {
            match state.canister_state(&canister_id) {
                Some(canister) => {
                    if !canister.controllers().contains(&sender.get()) {
                        Err(permission_denied_error(
                            "Requested canister rejected the message",
                        ))
                    } else {
                        Ok(())
                    }
                }
                None => Err(not_found_error("Requested canister does not exist")),
            }
        }

        let rejected_canister_err = Err(permission_denied_error(
            "Requested canister rejected the message",
        ));
        // The message is targeted towards the management canister. The
        // actual type of the method will determine if the message should be
        // accepted or not.
        match Ic00Method::from_str(method_name) {
            // The method is either invalid or it is of a type that users
            // are not allowed to send.
            Err(_)
            | Ok(Ic00Method::CreateCanister)
            | Ok(Ic00Method::SetupInitialDKG)
            | Ok(Ic00Method::SignWithECDSA)
            | Ok(Ic00Method::GetMockECDSAPublicKey)
            | Ok(Ic00Method::SignWithMockECDSA)
            // "DepositCycles" can be called by anyone however as ingress message
            // cannot carry cycles, it does not make sense to allow them from users.
            | Ok(Ic00Method::DepositCycles) => rejected_canister_err,

            // These methods are only valid if they are sent by the controller
            // of the canister. We assume that the canister always wants to
            // accept messages from its controller.
            Ok(Ic00Method::CanisterStatus)
            | Ok(Ic00Method::StartCanister)
            | Ok(Ic00Method::UninstallCode)
            | Ok(Ic00Method::StopCanister)
            | Ok(Ic00Method::DeleteCanister) => match Decode!(payload, CanisterIdRecord) {
                Err(_) => rejected_canister_err,
                Ok(args) => is_sender_controller(args.get_canister_id(), sender, state),
            },
            Ok(Ic00Method::UpdateSettings) => match Decode!(payload, UpdateSettingsArgs) {
                Err(_) => rejected_canister_err,
                Ok(args) => is_sender_controller(args.get_canister_id(), sender, state),
            },
            Ok(Ic00Method::InstallCode) => match Decode!(payload, InstallCodeArgs) {
                Err(_) => rejected_canister_err,
                Ok(args) => is_sender_controller(args.get_canister_id(), sender, state),
            },
            Ok(Ic00Method::SetController) => match Decode!(payload, SetControllerArgs) {
                Err(_) => rejected_canister_err,
                Ok(args) => is_sender_controller(args.get_canister_id(), sender, state),
            },

            // Nobody pays for `raw_rand`, so this cannot be used via ingress messages
            Ok(Ic00Method::RawRand) => rejected_canister_err,

            Ok(Ic00Method::ProvisionalCreateCanisterWithCycles)
            | Ok(Ic00Method::ProvisionalTopUpCanister) => {
                if provisional_whitelist.contains(sender.get_ref()) {
                    Ok(())
                } else {
                    rejected_canister_err
                }
            }
        }
    }
/// Checks if a given ingress message directed to the management canister
/// should be accepted or not.
Checks if a given ingress message directed to the management canister
should be accepted or not.
Checks if a given ingress message directed to the management canister should be accepted or not .
pub(crate) fn should_accept_ingress_message(
        &self,
        state: Arc<ReplicatedState>,
        provisional_whitelist: &ProvisionalWhitelist,
        sender: UserId,
        method_name: &str,
        payload: &[u8],
    ) -> Result<(), CanonicalError> {
        fn is_sender_controller(
            canister_id: CanisterId,
            sender: UserId,
            state: Arc<ReplicatedState>,
        ) -> Result<(), CanonicalError> {
            match state.canister_state(&canister_id) {
                Some(canister) => {
                    if !canister.controllers().contains(&sender.get()) {
                        Err(permission_denied_error(
                            "Requested canister rejected the message",
                        ))
                    } else {
                        Ok(())
                    }
                }
                None => Err(not_found_error("Requested canister does not exist")),
            }
        }
        let rejected_canister_err = Err(permission_denied_error(
            "Requested canister rejected the message",
        ));
        // The message is targeted towards the management canister. The
        // actual type of the method will determine if the message should be
        // accepted or not.
        match Ic00Method::from_str(method_name) {
            // The method is either invalid or it is of a type that users
            // are not allowed to send.
            Err(_)
            | Ok(Ic00Method::CreateCanister)
            | Ok(Ic00Method::SetupInitialDKG)
            | Ok(Ic00Method::SignWithECDSA)
            | Ok(Ic00Method::GetMockECDSAPublicKey)
            | Ok(Ic00Method::SignWithMockECDSA)
            // "DepositCycles" can be called by anyone however as ingress message
            // cannot carry cycles, it does not make sense to allow them from users.
            | Ok(Ic00Method::DepositCycles) => rejected_canister_err,
            // These methods are only valid if they are sent by the controller
            // of the canister. We assume that the canister always wants to
            // accept messages from its controller.
            Ok(Ic00Method::CanisterStatus)
            | Ok(Ic00Method::StartCanister)
            | Ok(Ic00Method::UninstallCode)
            | Ok(Ic00Method::StopCanister)
            | Ok(Ic00Method::DeleteCanister) => match Decode!(payload, CanisterIdRecord) {
                Err(_) => rejected_canister_err,
                Ok(args) => is_sender_controller(args.get_canister_id(), sender, state),
            },
            Ok(Ic00Method::UpdateSettings) => match Decode!(payload, UpdateSettingsArgs) {
                Err(_) => rejected_canister_err,
                Ok(args) => is_sender_controller(args.get_canister_id(), sender, state),
            },
            Ok(Ic00Method::InstallCode) => match Decode!(payload, InstallCodeArgs) {
                Err(_) => rejected_canister_err,
                Ok(args) => is_sender_controller(args.get_canister_id(), sender, state),
            },
            Ok(Ic00Method::SetController) => match Decode!(payload, SetControllerArgs) {
                Err(_) => rejected_canister_err,
                Ok(args) => is_sender_controller(args.get_canister_id(), sender, state),
            },
            // Nobody pays for `raw_rand`, so this cannot be used via ingress messages
            Ok(Ic00Method::RawRand) => rejected_canister_err,
            Ok(Ic00Method::ProvisionalCreateCanisterWithCycles)
            | Ok(Ic00Method::ProvisionalTopUpCanister) => {
                if provisional_whitelist.contains(sender.get_ref()) {
                    Ok(())
                } else {
                    rejected_canister_err
                }
            }
        }
    }
pub ( crate ) fn should_accept_ingress_message ( & self , state : Arc < ReplicatedState > , provisional_whitelist : & ProvisionalWhitelist , sender : UserId , method_name : & str , payload : & [ u8 ] , ) -> Result < ( ) , CanonicalError > { fn is_sender_controller ( canister_id : CanisterId , sender : UserId , state : Arc < ReplicatedState > , ) -> Result < ( ) , CanonicalError > { match state . canister_state ( & canister_id ) { Some ( canister ) => { if ! canister . controllers ( ) . contains ( & sender . get ( ) ) { Err ( permission_denied_error ( " " , ) ) } else { Ok ( ( ) ) } } None => Err ( not_found_error ( " " ) ) , } } let rejected_canister_err = Err ( permission_denied_error ( " " , ) ) ; // The message is targeted towards the management canister. The // actual type of the method will determine if the message should be // accepted or not. match Ic00Method :: from_str ( method_name ) { // The method is either invalid or it is of a type that users // are not allowed to send. Err ( _ ) | Ok ( Ic00Method :: CreateCanister ) | Ok ( Ic00Method :: SetupInitialDKG ) | Ok ( Ic00Method :: SignWithECDSA ) | Ok ( Ic00Method :: GetMockECDSAPublicKey ) | Ok ( Ic00Method :: SignWithMockECDSA ) // "DepositCycles" can be called by anyone however as ingress message // cannot carry cycles, it does not make sense to allow them from users. | Ok ( Ic00Method :: DepositCycles ) => rejected_canister_err , // These methods are only valid if they are sent by the controller // of the canister. We assume that the canister always wants to // accept messages from its controller. Ok ( Ic00Method :: CanisterStatus ) | Ok ( Ic00Method :: StartCanister ) | Ok ( Ic00Method :: UninstallCode ) | Ok ( Ic00Method :: StopCanister ) | Ok ( Ic00Method :: DeleteCanister ) => match Decode ! ( payload CanisterIdRecord ) { Err ( _ ) => rejected_canister_err , Ok ( args ) => is_sender_controller ( args . get_canister_id ( ) , sender , state ) , } , Ok ( Ic00Method :: UpdateSettings ) => match Decode ! ( payload UpdateSettingsArgs ) { Err ( _ ) => rejected_canister_err , Ok ( args ) => is_sender_controller ( args . get_canister_id ( ) , sender , state ) , } , Ok ( Ic00Method :: InstallCode ) => match Decode ! ( payload InstallCodeArgs ) { Err ( _ ) => rejected_canister_err , Ok ( args ) => is_sender_controller ( args . get_canister_id ( ) , sender , state ) , } , Ok ( Ic00Method :: SetController ) => match Decode ! ( payload SetControllerArgs ) { Err ( _ ) => rejected_canister_err , Ok ( args ) => is_sender_controller ( args . get_canister_id ( ) , sender , state ) , } , // Nobody pays for `raw_rand`, so this cannot be used via ingress messages Ok ( Ic00Method :: RawRand ) => rejected_canister_err , Ok ( Ic00Method :: ProvisionalCreateCanisterWithCycles ) | Ok ( Ic00Method :: ProvisionalTopUpCanister ) => { if provisional_whitelist . contains ( sender . get_ref ( ) ) { Ok ( ( ) ) } else { rejected_canister_err } } } }
Checks if a given ingress message directed to the management canister
should be accepted or not.
Checks if a given ingress message directed to the management canister should be accepted or not .
&self
state
Arc<ReplicatedState>
provisional_whitelist
&ProvisionalWhitelist
sender
UserId
method_name
&str
payload
&[u8]
&self
state
Arc<ReplicatedState>
provisional_whitelist
&ProvisionalWhitelist
sender
UserId
method_name
&str
payload
&[u8]