1use crate::bank::{Bank, BankKeeper, BankSudo};
2use crate::contracts::Contract;
3use crate::error::std_error_bail;
4use crate::executor::{AppResponse, Executor};
5use crate::featured::staking::{
6 Distribution, DistributionKeeper, StakeKeeper, Staking, StakingSudo,
7};
8use crate::gov::Gov;
9use crate::ibc::Ibc;
10use crate::module::{FailingModule, Module};
11use crate::prefixed_storage::{
12 prefixed, prefixed_multilevel, prefixed_multilevel_read, prefixed_read,
13};
14use crate::transactions::transactional;
15use crate::wasm::{ContractData, Wasm, WasmKeeper, WasmSudo};
16use crate::{AppBuilder, GovFailingModule, IbcFailingModule, Stargate, StargateFailing};
17use cosmwasm_std::testing::{MockApi, MockStorage};
18use cosmwasm_std::{
19 from_json, to_json_binary, Addr, Api, Binary, BlockInfo, ContractResult, CosmosMsg, CustomMsg,
20 CustomQuery, Empty, Querier, QuerierResult, QuerierWrapper, QueryRequest, Record, StdError,
21 StdResult, Storage, SystemError, SystemResult,
22};
23use serde::{de::DeserializeOwned, Serialize};
24use std::fmt::Debug;
25use std::marker::PhantomData;
26
27pub fn next_block(block: &mut BlockInfo) {
30 block.time = block.time.plus_seconds(5);
31 block.height += 1;
32}
33
34pub type BasicApp<ExecC = Empty, QueryC = Empty> = App<
37 BankKeeper,
38 MockApi,
39 MockStorage,
40 FailingModule<ExecC, QueryC, Empty>,
41 WasmKeeper<ExecC, QueryC>,
42 StakeKeeper,
43 DistributionKeeper,
44 IbcFailingModule,
45 GovFailingModule,
46 StargateFailing,
47>;
48
49#[derive(Clone)]
53pub struct App<
54 Bank = BankKeeper,
55 Api = MockApi,
56 Storage = MockStorage,
57 Custom = FailingModule<Empty, Empty, Empty>,
58 Wasm = WasmKeeper<Empty, Empty>,
59 Staking = StakeKeeper,
60 Distr = DistributionKeeper,
61 Ibc = IbcFailingModule,
62 Gov = GovFailingModule,
63 Stargate = StargateFailing,
64> {
65 pub(crate) router: Router<Bank, Custom, Wasm, Staking, Distr, Ibc, Gov, Stargate>,
66 pub(crate) api: Api,
67 pub(crate) storage: Storage,
68 pub(crate) block: BlockInfo,
69}
70
71pub fn no_init<ApiT, BankT, CustomT, WasmT, StakingT, DistrT, IbcT, GovT, StargateT>(
73 router: &mut Router<BankT, CustomT, WasmT, StakingT, DistrT, IbcT, GovT, StargateT>,
74 api: &ApiT,
75 storage: &mut dyn Storage,
76) {
77 let _ = (router, api, storage);
78}
79
80impl Default for BasicApp {
81 fn default() -> Self {
82 Self::new(no_init)
83 }
84}
85
86impl BasicApp {
87 pub fn new<F>(init_fn: F) -> Self
89 where
90 F: FnOnce(
91 &mut Router<
92 BankKeeper,
93 FailingModule<Empty, Empty, Empty>,
94 WasmKeeper<Empty, Empty>,
95 StakeKeeper,
96 DistributionKeeper,
97 IbcFailingModule,
98 GovFailingModule,
99 StargateFailing,
100 >,
101 &MockApi,
102 &mut dyn Storage,
103 ),
104 {
105 AppBuilder::new().build(init_fn)
106 }
107}
108
109pub fn custom_app<ExecC, QueryC, F>(init_fn: F) -> BasicApp<ExecC, QueryC>
112where
113 ExecC: CustomMsg + DeserializeOwned + 'static,
114 QueryC: Debug + CustomQuery + DeserializeOwned + 'static,
115 F: FnOnce(
116 &mut Router<
117 BankKeeper,
118 FailingModule<ExecC, QueryC, Empty>,
119 WasmKeeper<ExecC, QueryC>,
120 StakeKeeper,
121 DistributionKeeper,
122 IbcFailingModule,
123 GovFailingModule,
124 StargateFailing,
125 >,
126 &MockApi,
127 &mut dyn Storage,
128 ),
129{
130 AppBuilder::new_custom().build(init_fn)
131}
132
133impl<BankT, ApiT, StorageT, CustomT, WasmT, StakingT, DistrT, IbcT, GovT, StargateT> Querier
134 for App<BankT, ApiT, StorageT, CustomT, WasmT, StakingT, DistrT, IbcT, GovT, StargateT>
135where
136 CustomT::ExecT: CustomMsg + DeserializeOwned + 'static,
137 CustomT::QueryT: CustomQuery + DeserializeOwned + 'static,
138 WasmT: Wasm<CustomT::ExecT, CustomT::QueryT>,
139 BankT: Bank,
140 ApiT: Api,
141 StorageT: Storage,
142 CustomT: Module,
143 StakingT: Staking,
144 DistrT: Distribution,
145 IbcT: Ibc,
146 GovT: Gov,
147 StargateT: Stargate,
148{
149 fn raw_query(&self, bin_request: &[u8]) -> QuerierResult {
150 self.router
151 .querier(&self.api, &self.storage, &self.block)
152 .raw_query(bin_request)
153 }
154}
155
156impl<BankT, ApiT, StorageT, CustomT, WasmT, StakingT, DistrT, IbcT, GovT, StargateT>
157 Executor<CustomT::ExecT>
158 for App<BankT, ApiT, StorageT, CustomT, WasmT, StakingT, DistrT, IbcT, GovT, StargateT>
159where
160 CustomT::ExecT: CustomMsg + DeserializeOwned + 'static,
161 CustomT::QueryT: CustomQuery + DeserializeOwned + 'static,
162 WasmT: Wasm<CustomT::ExecT, CustomT::QueryT>,
163 BankT: Bank,
164 ApiT: Api,
165 StorageT: Storage,
166 CustomT: Module,
167 StakingT: Staking,
168 DistrT: Distribution,
169 IbcT: Ibc,
170 GovT: Gov,
171 StargateT: Stargate,
172{
173 fn execute(&mut self, sender: Addr, msg: CosmosMsg<CustomT::ExecT>) -> StdResult<AppResponse> {
174 let mut all = self.execute_multi(sender, vec![msg])?;
175 let res = all.pop().unwrap();
176 Ok(res)
177 }
178}
179
180impl<BankT, ApiT, StorageT, CustomT, WasmT, StakingT, DistrT, IbcT, GovT, StargateT>
181 App<BankT, ApiT, StorageT, CustomT, WasmT, StakingT, DistrT, IbcT, GovT, StargateT>
182where
183 WasmT: Wasm<CustomT::ExecT, CustomT::QueryT>,
184 BankT: Bank,
185 ApiT: Api,
186 StorageT: Storage,
187 CustomT: Module,
188 StakingT: Staking,
189 DistrT: Distribution,
190 IbcT: Ibc,
191 GovT: Gov,
192 StargateT: Stargate,
193{
194 pub fn router(
196 &self,
197 ) -> &Router<BankT, CustomT, WasmT, StakingT, DistrT, IbcT, GovT, StargateT> {
198 &self.router
199 }
200
201 pub fn api(&self) -> &ApiT {
203 &self.api
204 }
205
206 pub fn storage(&self) -> &StorageT {
208 &self.storage
209 }
210
211 pub fn storage_mut(&mut self) -> &mut StorageT {
213 &mut self.storage
214 }
215
216 pub fn init_modules<F, T>(&mut self, init_fn: F) -> T
218 where
219 F: FnOnce(
220 &mut Router<BankT, CustomT, WasmT, StakingT, DistrT, IbcT, GovT, StargateT>,
221 &ApiT,
222 &mut dyn Storage,
223 ) -> T,
224 {
225 init_fn(&mut self.router, &self.api, &mut self.storage)
226 }
227
228 pub fn read_module<F, T>(&self, query_fn: F) -> T
230 where
231 F: FnOnce(
232 &Router<BankT, CustomT, WasmT, StakingT, DistrT, IbcT, GovT, StargateT>,
233 &ApiT,
234 &dyn Storage,
235 ) -> T,
236 {
237 query_fn(&self.router, &self.api, &self.storage)
238 }
239}
240
241impl<BankT, ApiT, StorageT, CustomT, WasmT, StakingT, DistrT, IbcT, GovT, StargateT>
244 App<BankT, ApiT, StorageT, CustomT, WasmT, StakingT, DistrT, IbcT, GovT, StargateT>
245where
246 BankT: Bank,
247 ApiT: Api,
248 StorageT: Storage,
249 CustomT: Module,
250 WasmT: Wasm<CustomT::ExecT, CustomT::QueryT>,
251 StakingT: Staking,
252 DistrT: Distribution,
253 IbcT: Ibc,
254 GovT: Gov,
255 StargateT: Stargate,
256 CustomT::ExecT: CustomMsg + DeserializeOwned + 'static,
257 CustomT::QueryT: CustomQuery + DeserializeOwned + 'static,
258{
259 pub fn store_code(&mut self, code: Box<dyn Contract<CustomT::ExecT, CustomT::QueryT>>) -> u64 {
262 self.router
263 .wasm
264 .store_code(MockApi::default().addr_make("creator"), code)
265 }
266
267 pub fn store_code_with_creator(
270 &mut self,
271 creator: Addr,
272 code: Box<dyn Contract<CustomT::ExecT, CustomT::QueryT>>,
273 ) -> u64 {
274 self.router.wasm.store_code(creator, code)
275 }
276
277 pub fn store_code_with_id(
280 &mut self,
281 creator: Addr,
282 code_id: u64,
283 code: Box<dyn Contract<CustomT::ExecT, CustomT::QueryT>>,
284 ) -> StdResult<u64> {
285 self.router.wasm.store_code_with_id(creator, code_id, code)
286 }
287
288 pub fn duplicate_code(&mut self, code_id: u64) -> StdResult<u64> {
337 self.router.wasm.duplicate_code(code_id)
338 }
339
340 pub fn contract_data(&self, address: &Addr) -> StdResult<ContractData> {
342 self.router.wasm.contract_data(&self.storage, address)
343 }
344
345 pub fn dump_wasm_raw(&self, address: &Addr) -> Vec<Record> {
347 self.router.wasm.dump_wasm_raw(&self.storage, address)
348 }
349
350 pub fn contract_storage<'a>(&'a self, contract_addr: &Addr) -> Box<dyn Storage + 'a> {
352 self.router
353 .wasm
354 .contract_storage(&self.storage, contract_addr)
355 }
356
357 pub fn contract_storage_mut<'a>(&'a mut self, contract_addr: &Addr) -> Box<dyn Storage + 'a> {
359 self.router
360 .wasm
361 .contract_storage_mut(&mut self.storage, contract_addr)
362 }
363
364 pub fn prefixed_storage<'a>(&'a self, namespace: &[u8]) -> Box<dyn Storage + 'a> {
366 Box::new(prefixed_read(&self.storage, namespace))
367 }
368
369 pub fn prefixed_storage_mut<'a>(&'a mut self, namespace: &[u8]) -> Box<dyn Storage + 'a> {
371 Box::new(prefixed(&mut self.storage, namespace))
372 }
373
374 pub fn prefixed_multilevel_storage<'a>(
376 &'a self,
377 namespaces: &[&[u8]],
378 ) -> Box<dyn Storage + 'a> {
379 Box::new(prefixed_multilevel_read(&self.storage, namespaces))
380 }
381
382 pub fn prefixed_multilevel_storage_mut<'a>(
384 &'a mut self,
385 namespaces: &[&[u8]],
386 ) -> Box<dyn Storage + 'a> {
387 Box::new(prefixed_multilevel(&mut self.storage, namespaces))
388 }
389}
390
391impl<BankT, ApiT, StorageT, CustomT, WasmT, StakingT, DistrT, IbcT, GovT, StargateT>
392 App<BankT, ApiT, StorageT, CustomT, WasmT, StakingT, DistrT, IbcT, GovT, StargateT>
393where
394 CustomT::ExecT: CustomMsg + DeserializeOwned + 'static,
395 CustomT::QueryT: CustomQuery + DeserializeOwned + 'static,
396 WasmT: Wasm<CustomT::ExecT, CustomT::QueryT>,
397 BankT: Bank,
398 ApiT: Api,
399 StorageT: Storage,
400 CustomT: Module,
401 StakingT: Staking,
402 DistrT: Distribution,
403 IbcT: Ibc,
404 GovT: Gov,
405 StargateT: Stargate,
406{
407 pub fn set_block(&mut self, block: BlockInfo) {
409 self.block = block;
410 self.router
411 .staking
412 .process_queue(&self.api, &mut self.storage, &self.router, &self.block)
413 .unwrap();
414 }
415
416 pub fn update_block<F: Fn(&mut BlockInfo)>(&mut self, action: F) {
418 action(&mut self.block);
419 self.router
420 .staking
421 .process_queue(&self.api, &mut self.storage, &self.router, &self.block)
422 .unwrap();
423 }
424
425 pub fn block_info(&self) -> BlockInfo {
427 self.block.clone()
428 }
429
430 pub fn wrap(&self) -> QuerierWrapper<CustomT::QueryT> {
433 QuerierWrapper::new(self)
434 }
435
436 pub fn execute_multi(
440 &mut self,
441 sender: Addr,
442 msgs: Vec<CosmosMsg<CustomT::ExecT>>,
443 ) -> StdResult<Vec<AppResponse>> {
444 let Self {
449 block,
450 router,
451 api,
452 storage,
453 } = self;
454
455 transactional(&mut *storage, |write_cache, _| {
456 msgs.into_iter()
457 .map(|msg| router.execute(&*api, write_cache, block, sender.clone(), msg))
458 .collect()
459 })
460 }
461
462 pub fn wasm_sudo<T: Serialize, U: Into<Addr>>(
466 &mut self,
467 contract_addr: U,
468 msg: &T,
469 ) -> StdResult<AppResponse> {
470 let msg = WasmSudo {
471 contract_addr: contract_addr.into(),
472 message: to_json_binary(msg)?,
473 };
474
475 let Self {
476 block,
477 router,
478 api,
479 storage,
480 } = self;
481
482 transactional(&mut *storage, |write_cache, _| {
483 router.wasm.sudo(&*api, write_cache, router, block, msg)
484 })
485 }
486
487 pub fn sudo(&mut self, msg: SudoMsg) -> StdResult<AppResponse> {
491 let Self {
495 block,
496 router,
497 api,
498 storage,
499 } = self;
500
501 transactional(&mut *storage, |write_cache, _| {
502 router.sudo(&*api, write_cache, block, msg)
503 })
504 }
505}
506#[derive(Clone)]
509pub struct Router<Bank, Custom, Wasm, Staking, Distr, Ibc, Gov, Stargate> {
510 pub(crate) wasm: Wasm,
512 pub bank: Bank,
514 pub custom: Custom,
516 pub staking: Staking,
518 pub distribution: Distr,
520 pub ibc: Ibc,
522 pub gov: Gov,
524 pub stargate: Stargate,
526}
527
528impl<BankT, CustomT, WasmT, StakingT, DistrT, IbcT, GovT, StargateT>
529 Router<BankT, CustomT, WasmT, StakingT, DistrT, IbcT, GovT, StargateT>
530where
531 CustomT::ExecT: CustomMsg + DeserializeOwned + 'static,
532 CustomT::QueryT: CustomQuery + DeserializeOwned + 'static,
533 CustomT: Module,
534 WasmT: Wasm<CustomT::ExecT, CustomT::QueryT>,
535 BankT: Bank,
536 StakingT: Staking,
537 DistrT: Distribution,
538 IbcT: Ibc,
539 GovT: Gov,
540 StargateT: Stargate,
541{
542 pub fn querier<'a>(
544 &'a self,
545 api: &'a dyn Api,
546 storage: &'a dyn Storage,
547 block_info: &'a BlockInfo,
548 ) -> RouterQuerier<'a, CustomT::ExecT, CustomT::QueryT> {
549 RouterQuerier {
550 router: self,
551 api,
552 storage,
553 block_info,
554 }
555 }
556}
557
558pub enum SudoMsg {
561 Bank(BankSudo),
563 Custom(Empty),
565 Staking(StakingSudo),
567 Wasm(WasmSudo),
569}
570
571impl From<WasmSudo> for SudoMsg {
572 fn from(wasm: WasmSudo) -> Self {
573 SudoMsg::Wasm(wasm)
574 }
575}
576
577impl From<BankSudo> for SudoMsg {
578 fn from(bank: BankSudo) -> Self {
579 SudoMsg::Bank(bank)
580 }
581}
582
583impl From<StakingSudo> for SudoMsg {
584 fn from(staking: StakingSudo) -> Self {
585 SudoMsg::Staking(staking)
586 }
587}
588pub trait CosmosRouter {
594 type ExecC: CustomMsg;
596 type QueryC: CustomQuery;
598
599 fn execute(
601 &self,
602 api: &dyn Api,
603 storage: &mut dyn Storage,
604 block: &BlockInfo,
605 sender: Addr,
606 msg: CosmosMsg<Self::ExecC>,
607 ) -> StdResult<AppResponse>;
608
609 fn query(
611 &self,
612 api: &dyn Api,
613 storage: &dyn Storage,
614 block: &BlockInfo,
615 request: QueryRequest<Self::QueryC>,
616 ) -> StdResult<Binary>;
617
618 fn sudo(
620 &self,
621 api: &dyn Api,
622 storage: &mut dyn Storage,
623 block: &BlockInfo,
624 msg: SudoMsg,
625 ) -> StdResult<AppResponse>;
626}
627
628impl<BankT, CustomT, WasmT, StakingT, DistrT, IbcT, GovT, StargateT> CosmosRouter
629 for Router<BankT, CustomT, WasmT, StakingT, DistrT, IbcT, GovT, StargateT>
630where
631 CustomT::ExecT: CustomMsg + DeserializeOwned + 'static,
632 CustomT::QueryT: CustomQuery + DeserializeOwned + 'static,
633 CustomT: Module,
634 WasmT: Wasm<CustomT::ExecT, CustomT::QueryT>,
635 BankT: Bank,
636 StakingT: Staking,
637 DistrT: Distribution,
638 IbcT: Ibc,
639 GovT: Gov,
640 StargateT: Stargate,
641{
642 type ExecC = CustomT::ExecT;
643 type QueryC = CustomT::QueryT;
644
645 fn execute(
646 &self,
647 api: &dyn Api,
648 storage: &mut dyn Storage,
649 block: &BlockInfo,
650 sender: Addr,
651 msg: CosmosMsg<Self::ExecC>,
652 ) -> StdResult<AppResponse> {
653 match msg {
654 CosmosMsg::Wasm(msg) => self.wasm.execute(api, storage, self, block, sender, msg),
655 CosmosMsg::Bank(msg) => self.bank.execute(api, storage, self, block, sender, msg),
656 CosmosMsg::Custom(msg) => self.custom.execute(api, storage, self, block, sender, msg),
657 #[cfg(feature = "staking")]
658 CosmosMsg::Staking(msg) => self.staking.execute(api, storage, self, block, sender, msg),
659 #[cfg(feature = "staking")]
660 CosmosMsg::Distribution(msg) => self
661 .distribution
662 .execute(api, storage, self, block, sender, msg),
663 #[cfg(feature = "stargate")]
664 CosmosMsg::Ibc(msg) => self.ibc.execute(api, storage, self, block, sender, msg),
665 #[cfg(feature = "stargate")]
666 CosmosMsg::Gov(msg) => self.gov.execute(api, storage, self, block, sender, msg),
667 #[allow(deprecated)]
668 #[cfg(feature = "stargate")]
669 CosmosMsg::Stargate { type_url, value } => self
670 .stargate
671 .execute_stargate(api, storage, self, block, sender, type_url, value),
672 #[cfg(feature = "cosmwasm_2_0")]
673 CosmosMsg::Any(msg) => self
674 .stargate
675 .execute_any(api, storage, self, block, sender, msg),
676 _ => std_error_bail!("Cannot execute {:?}", msg),
677 }
678 }
679
680 fn query(
684 &self,
685 api: &dyn Api,
686 storage: &dyn Storage,
687 block: &BlockInfo,
688 request: QueryRequest<Self::QueryC>,
689 ) -> StdResult<Binary> {
690 let querier = self.querier(api, storage, block);
691 match request {
692 QueryRequest::Wasm(req) => self.wasm.query(api, storage, &querier, block, req),
693 QueryRequest::Bank(req) => self.bank.query(api, storage, &querier, block, req),
694 QueryRequest::Custom(req) => self.custom.query(api, storage, &querier, block, req),
695 #[cfg(feature = "staking")]
696 QueryRequest::Staking(req) => self.staking.query(api, storage, &querier, block, req),
697 #[cfg(all(feature = "cosmwasm_1_3", feature = "staking"))]
698 QueryRequest::Distribution(req) => {
699 self.distribution.query(api, storage, &querier, block, req)
700 }
701 #[cfg(feature = "stargate")]
702 QueryRequest::Ibc(req) => self.ibc.query(api, storage, &querier, block, req),
703 #[allow(deprecated)]
704 #[cfg(feature = "stargate")]
705 QueryRequest::Stargate { path, data } => self
706 .stargate
707 .query_stargate(api, storage, &querier, block, path, data),
708 #[cfg(feature = "cosmwasm_2_0")]
709 QueryRequest::Grpc(req) => self.stargate.query_grpc(api, storage, &querier, block, req),
710 _ => unimplemented!(),
711 }
712 }
713
714 fn sudo(
715 &self,
716 api: &dyn Api,
717 storage: &mut dyn Storage,
718 block: &BlockInfo,
719 msg: SudoMsg,
720 ) -> StdResult<AppResponse> {
721 match msg {
722 SudoMsg::Wasm(msg) => self.wasm.sudo(api, storage, self, block, msg),
723 SudoMsg::Bank(msg) => self.bank.sudo(api, storage, self, block, msg),
724 #[cfg(feature = "staking")]
725 SudoMsg::Staking(msg) => self.staking.sudo(api, storage, self, block, msg),
726 _ => unimplemented!(),
727 }
728 }
729}
730
731pub struct MockRouter<ExecC, QueryC>(PhantomData<(ExecC, QueryC)>);
732
733impl Default for MockRouter<Empty, Empty> {
734 fn default() -> Self {
735 Self::new()
736 }
737}
738
739impl<ExecC, QueryC> MockRouter<ExecC, QueryC> {
740 pub fn new() -> Self
741 where
742 QueryC: CustomQuery,
743 {
744 MockRouter(PhantomData)
745 }
746}
747
748impl<ExecC, QueryC> CosmosRouter for MockRouter<ExecC, QueryC>
749where
750 ExecC: CustomMsg,
751 QueryC: CustomQuery,
752{
753 type ExecC = ExecC;
754 type QueryC = QueryC;
755
756 fn execute(
757 &self,
758 _api: &dyn Api,
759 _storage: &mut dyn Storage,
760 _block: &BlockInfo,
761 _sender: Addr,
762 _msg: CosmosMsg<Self::ExecC>,
763 ) -> StdResult<AppResponse> {
764 panic!("Cannot execute MockRouters");
765 }
766
767 fn query(
768 &self,
769 _api: &dyn Api,
770 _storage: &dyn Storage,
771 _block: &BlockInfo,
772 _request: QueryRequest<Self::QueryC>,
773 ) -> StdResult<Binary> {
774 panic!("Cannot query MockRouters");
775 }
776
777 fn sudo(
778 &self,
779 _api: &dyn Api,
780 _storage: &mut dyn Storage,
781 _block: &BlockInfo,
782 _msg: SudoMsg,
783 ) -> StdResult<AppResponse> {
784 panic!("Cannot sudo MockRouters");
785 }
786}
787
788pub struct RouterQuerier<'a, ExecC, QueryC> {
789 router: &'a dyn CosmosRouter<ExecC = ExecC, QueryC = QueryC>,
790 api: &'a dyn Api,
791 storage: &'a dyn Storage,
792 block_info: &'a BlockInfo,
793}
794
795impl<'a, ExecC, QueryC> RouterQuerier<'a, ExecC, QueryC> {
796 pub fn new(
797 router: &'a dyn CosmosRouter<ExecC = ExecC, QueryC = QueryC>,
798 api: &'a dyn Api,
799 storage: &'a dyn Storage,
800 block_info: &'a BlockInfo,
801 ) -> Self {
802 Self {
803 router,
804 api,
805 storage,
806 block_info,
807 }
808 }
809}
810
811impl<ExecC, QueryC> Querier for RouterQuerier<'_, ExecC, QueryC>
812where
813 ExecC: CustomMsg + DeserializeOwned + 'static,
814 QueryC: CustomQuery + DeserializeOwned + 'static,
815{
816 fn raw_query(&self, bin_request: &[u8]) -> QuerierResult {
817 let request: QueryRequest<QueryC> = match from_json(bin_request) {
818 Ok(v) => v,
819 Err(e) => {
820 return SystemResult::Err(SystemError::InvalidRequest {
821 error: format!("Parsing query request: {e}"),
822 request: bin_request.into(),
823 })
824 }
825 };
826 let contract_result: ContractResult<Binary> = self
827 .router
828 .query(self.api, self.storage, self.block_info, request)
829 .into();
830 SystemResult::Ok(contract_result)
831 }
832}