fn handle_response_with_canister_origin(
        &mut self,
        mut canister: CanisterState,
        originator: CanisterId,
        callback_id: CallbackId,
        call_context_id: CallContextId,
        execution_result: Result<Option<WasmResult>, HypervisorError>,
    ) -> Option<Result<WasmResult, UserError>> {
        let canister_id = canister.canister_id();
        // As we have executed a request on the canister earlier, it must
        // contain a call context manager hence the following should not fail.
        let call_context_manager = canister
            .system_state
            .call_context_manager_mut()
            .unwrap_or_else(|| {
                fatal!(
                    self.log,
                    "Canister {}: Expected to find a CallContextManager",
                    canister_id
                )
            });

        let logger = self.log;

        // A helper function to produce and enqueue `Response`s from
        // common fields.
        let mut enqueue_response = |payload: Payload| {
            let response = Response {
                originator,
                respondent: canister_id,
                originator_reply_callback: callback_id,
                response_payload: payload,
                refund: Cycles::zero(),
            };
            self.outstanding_response = Some(response);
        };

        use CallContextAction::*;
        match call_context_manager.on_canister_result(call_context_id, execution_result) {
            Reply { payload, refund } => {
                if !refund.is_zero() {
                    warn!(
                        logger,
                        "[EXC-BUG] No cycles are refunded in a response to a query call."
                    );
                }
                enqueue_response(Payload::Data(payload));
                // The canister has produced a response so remove any other
                // requests that it may have produced to minimize unnecessary
                // work.
                self.outstanding_requests
                    .retain(|request| request.sender != canister_id);
                None
            }

            Reject { payload, refund } => {
                if !refund.is_zero() {
                    warn!(
                        logger,
                        "[EXC-BUG] No cycles are refunded in a response to a query call."
                    );
                }
                enqueue_response(Payload::Reject(RejectContext::new(
                    RejectCode::CanisterReject,
                    payload,
                )));
                // The canister has produced a response so remove any other
                // requests that it may have produced to minimize unnecessary
                // work.
                self.outstanding_requests
                    .retain(|request| request.sender != canister_id);
                None
            }

            NoResponse { refund } => {
                if !refund.is_zero() {
                    warn!(
                        logger,
                        "[EXC-BUG] No cycles are refunded in a response to a query call."
                    );
                }
                enqueue_response(Payload::Reject(RejectContext::new(
                    RejectCode::CanisterReject,
                    "Canister did not reply".to_string(),
                )));
                None
            }

            Fail { error, refund } => {
                if !refund.is_zero() {
                    warn!(
                        logger,
                        "[EXC-BUG] No cycles are refunded in a response to a query call."
                    );
                }
                let user_error = error.into_user_error(&canister.canister_id());
                enqueue_response(Payload::Reject(RejectContext::from(user_error)));
                None
            }

            // No response available and there are still outstanding
            // callbacks so enqueue any produced requests and continue
            // processing the query context.
            NotYetResponded => match self.enqueue_requests(&mut canister) {
                EnqueueRequestsResult::LoopDetected => Some(Err(UserError::new(
                    ErrorCode::InterCanisterQueryLoopDetected,
                    LOOP_DETECTED_ERROR_MSG.to_string(),
                ))),
                EnqueueRequestsResult::NoMessages | EnqueueRequestsResult::MessagesEnqueued => {
                    self.canisters.insert(canister.canister_id(), canister);
                    None
                }
            },

            // This state indicates that the canister produced a
            // response or reject earlier and we continued to keep
            // executing it.  This should not happen as once the
            // canister has produced a response, we drop its state and
            // do not process further messages on it.
            AlreadyResponded => fatal!(
                self.log,
                "Canister {}: Should not be possible to keep executing after producing a response",
                canister.canister_id()
            ),
        }
    }
// Handles execution results for canister where the sender of the request is
// a canister. Any produced response must be enqueued for further handling.
Handles execution results for canister where the sender of the request is
a canister. Any produced response must be enqueued for further handling.
Handles execution results for canister where the sender of the request is a canister . Any produced response must be enqueued for further handling .
fn handle_response_with_canister_origin(
        &mut self,
        mut canister: CanisterState,
        originator: CanisterId,
        callback_id: CallbackId,
        call_context_id: CallContextId,
        execution_result: Result<Option<WasmResult>, HypervisorError>,
    ) -> Option<Result<WasmResult, UserError>> {
        let canister_id = canister.canister_id();
        // As we have executed a request on the canister earlier, it must
        // contain a call context manager hence the following should not fail.
        let call_context_manager = canister
            .system_state
            .call_context_manager_mut()
            .unwrap_or_else(|| {
                fatal!(
                    self.log,
                    "Canister {}: Expected to find a CallContextManager",
                    canister_id
                )
            });
        let logger = self.log;
        // A helper function to produce and enqueue `Response`s from
        // common fields.
        let mut enqueue_response = |payload: Payload| {
            let response = Response {
                originator,
                respondent: canister_id,
                originator_reply_callback: callback_id,
                response_payload: payload,
                refund: Cycles::zero(),
            };
            self.outstanding_response = Some(response);
        };
        use CallContextAction::*;
        match call_context_manager.on_canister_result(call_context_id, execution_result) {
            Reply { payload, refund } => {
                if !refund.is_zero() {
                    warn!(
                        logger,
                        "[EXC-BUG] No cycles are refunded in a response to a query call."
                    );
                }
                enqueue_response(Payload::Data(payload));
                // The canister has produced a response so remove any other
                // requests that it may have produced to minimize unnecessary
                // work.
                self.outstanding_requests
                    .retain(|request| request.sender != canister_id);
                None
            }
            Reject { payload, refund } => {
                if !refund.is_zero() {
                    warn!(
                        logger,
                        "[EXC-BUG] No cycles are refunded in a response to a query call."
                    );
                }
                enqueue_response(Payload::Reject(RejectContext::new(
                    RejectCode::CanisterReject,
                    payload,
                )));
                // The canister has produced a response so remove any other
                // requests that it may have produced to minimize unnecessary
                // work.
                self.outstanding_requests
                    .retain(|request| request.sender != canister_id);
                None
            }
            NoResponse { refund } => {
                if !refund.is_zero() {
                    warn!(
                        logger,
                        "[EXC-BUG] No cycles are refunded in a response to a query call."
                    );
                }
                enqueue_response(Payload::Reject(RejectContext::new(
                    RejectCode::CanisterReject,
                    "Canister did not reply".to_string(),
                )));
                None
            }
            Fail { error, refund } => {
                if !refund.is_zero() {
                    warn!(
                        logger,
                        "[EXC-BUG] No cycles are refunded in a response to a query call."
                    );
                }
                let user_error = error.into_user_error(&canister.canister_id());
                enqueue_response(Payload::Reject(RejectContext::from(user_error)));
                None
            }
            // No response available and there are still outstanding
            // callbacks so enqueue any produced requests and continue
            // processing the query context.
            NotYetResponded => match self.enqueue_requests(&mut canister) {
                EnqueueRequestsResult::LoopDetected => Some(Err(UserError::new(
                    ErrorCode::InterCanisterQueryLoopDetected,
                    LOOP_DETECTED_ERROR_MSG.to_string(),
                ))),
                EnqueueRequestsResult::NoMessages | EnqueueRequestsResult::MessagesEnqueued => {
                    self.canisters.insert(canister.canister_id(), canister);
                    None
                }
            },
            // This state indicates that the canister produced a
            // response or reject earlier and we continued to keep
            // executing it.  This should not happen as once the
            // canister has produced a response, we drop its state and
            // do not process further messages on it.
            AlreadyResponded => fatal!(
                self.log,
                "Canister {}: Should not be possible to keep executing after producing a response",
                canister.canister_id()
            ),
        }
    }
fn handle_response_with_canister_origin ( & mut self , mut canister : CanisterState , originator : CanisterId , callback_id : CallbackId , call_context_id : CallContextId , execution_result : Result < Option < WasmResult > , HypervisorError > , ) -> Option < Result < WasmResult , UserError > > { let canister_id = canister . canister_id ( ) ; // As we have executed a request on the canister earlier, it must // contain a call context manager hence the following should not fail. let call_context_manager = canister . system_state . call_context_manager_mut ( ) . unwrap_or_else ( | | { fatal ! ( self log " " canister_id ) } ) ; let logger = self . log ; // A helper function to produce and enqueue `Response`s from // common fields. let mut enqueue_response = | payload : Payload | { let response = Response { originator , respondent : canister_id , originator_reply_callback : callback_id , response_payload : payload , refund : Cycles :: zero ( ) , } ; self . outstanding_response = Some ( response ) ; } ; use CallContextAction :: * ; match call_context_manager . on_canister_result ( call_context_id , execution_result ) { Reply { payload , refund } => { if ! refund . is_zero ( ) { warn ! ( logger " " ) ; } enqueue_response ( Payload :: Data ( payload ) ) ; // The canister has produced a response so remove any other // requests that it may have produced to minimize unnecessary // work. self . outstanding_requests . retain ( | request | request . sender != canister_id ) ; None } Reject { payload , refund } => { if ! refund . is_zero ( ) { warn ! ( logger " " ) ; } enqueue_response ( Payload :: Reject ( RejectContext :: new ( RejectCode :: CanisterReject , payload , ) ) ) ; // The canister has produced a response so remove any other // requests that it may have produced to minimize unnecessary // work. self . outstanding_requests . retain ( | request | request . sender != canister_id ) ; None } NoResponse { refund } => { if ! refund . is_zero ( ) { warn ! ( logger " " ) ; } enqueue_response ( Payload :: Reject ( RejectContext :: new ( RejectCode :: CanisterReject , " " . to_string ( ) , ) ) ) ; None } Fail { error , refund } => { if ! refund . is_zero ( ) { warn ! ( logger " " ) ; } let user_error = error . into_user_error ( & canister . canister_id ( ) ) ; enqueue_response ( Payload :: Reject ( RejectContext :: from ( user_error ) ) ) ; None } // No response available and there are still outstanding // callbacks so enqueue any produced requests and continue // processing the query context. NotYetResponded => match self . enqueue_requests ( & mut canister ) { EnqueueRequestsResult :: LoopDetected => Some ( Err ( UserError :: new ( ErrorCode :: InterCanisterQueryLoopDetected , LOOP_DETECTED_ERROR_MSG . to_string ( ) , ) ) ) , EnqueueRequestsResult :: NoMessages | EnqueueRequestsResult :: MessagesEnqueued => { self . canisters . insert ( canister . canister_id ( ) , canister ) ; None } } , // This state indicates that the canister produced a // response or reject earlier and we continued to keep // executing it.  This should not happen as once the // canister has produced a response, we drop its state and // do not process further messages on it. AlreadyResponded => fatal ! ( self log " " canister canister_id ( ) ) , } }
Handles execution results for canister where the sender of the request is
a canister.
Handles execution results for canister where the sender of the request is a canister .
&mut self
canister
CanisterState
originator
CanisterId
callback_id
CallbackId
call_context_id
CallContextId
execution_result
Result<Option<WasmResult>, HypervisorError>
&mut self
canister
CanisterState
originator
CanisterId
callback_id
CallbackId
call_context_id
CallContextId
execution_result
Result<Option<WasmResult>, HypervisorError>