1use crate::bank::{Bank, BankKeeper, BankSudo};
2use crate::contracts::Contract;
3use crate::error::{bail, AnyResult};
4use crate::executor::{AppResponse, Executor};
5use crate::gov::Gov;
6use crate::ibc::Ibc;
7use crate::module::{FailingModule, Module};
8use crate::prefixed_storage::{
9 prefixed, prefixed_multilevel, prefixed_multilevel_read, prefixed_read,
10};
11use crate::staking::{Distribution, DistributionKeeper, StakeKeeper, Staking, StakingSudo};
12use crate::stargate::{Stargate, StargateFailingModule};
13use crate::transactions::transactional;
14use crate::wasm::{ContractData, Wasm, WasmKeeper, WasmSudo};
15use crate::{AppBuilder, GovFailingModule, IbcFailingModule};
16use cosmwasm_std::testing::{MockApi, MockStorage};
17use cosmwasm_std::{
18 from_json, to_json_binary, Addr, Api, Binary, BlockInfo, ContractResult, CosmosMsg, CustomMsg,
19 CustomQuery, DepsMut, Empty, Env, Querier, QuerierResult, QuerierWrapper, QueryRequest, Record,
20 Response, Storage, SystemError, SystemResult,
21};
22use serde::{de::DeserializeOwned, Serialize};
23use std::fmt::Debug;
24use std::marker::PhantomData;
25
26pub fn next_block(block: &mut BlockInfo) {
29 block.time = block.time.plus_seconds(5);
30 block.height += 1;
31}
32
33pub type BasicApp<ExecC = Empty, QueryC = Empty> = App<
36 BankKeeper,
37 MockApi,
38 MockStorage,
39 FailingModule<ExecC, QueryC, Empty>,
40 WasmKeeper<ExecC, QueryC>,
41 StakeKeeper,
42 DistributionKeeper,
43 IbcFailingModule,
44 GovFailingModule,
45 StargateFailingModule,
46>;
47
48#[derive(Clone)]
52pub struct App<
53 Bank = BankKeeper,
54 Api = MockApi,
55 Storage = MockStorage,
56 Custom = FailingModule<Empty, Empty, Empty>,
57 Wasm = WasmKeeper<Empty, Empty>,
58 Staking = StakeKeeper,
59 Distr = DistributionKeeper,
60 Ibc = IbcFailingModule,
61 Gov = GovFailingModule,
62 Stargate = StargateFailingModule,
63> {
64 pub(crate) router: Router<Bank, Custom, Wasm, Staking, Distr, Ibc, Gov, Stargate>,
65 pub(crate) api: Api,
66 pub(crate) storage: Storage,
67 pub(crate) block: BlockInfo,
68}
69
70pub fn no_init<BankT, CustomT, WasmT, StakingT, DistrT, IbcT, GovT, StargateT>(
72 router: &mut Router<BankT, CustomT, WasmT, StakingT, DistrT, IbcT, GovT, StargateT>,
73 api: &dyn Api,
74 storage: &mut dyn Storage,
75) {
76 let _ = (router, api, storage);
77}
78
79impl Default for BasicApp {
80 fn default() -> Self {
81 Self::new(no_init)
82 }
83}
84
85impl BasicApp {
86 pub fn new<F>(init_fn: F) -> Self
88 where
89 F: FnOnce(
90 &mut Router<
91 BankKeeper,
92 FailingModule<Empty, Empty, Empty>,
93 WasmKeeper<Empty, Empty>,
94 StakeKeeper,
95 DistributionKeeper,
96 IbcFailingModule,
97 GovFailingModule,
98 StargateFailingModule,
99 >,
100 &dyn Api,
101 &mut dyn Storage,
102 ),
103 {
104 AppBuilder::new().build(init_fn)
105 }
106}
107
108pub fn custom_app<ExecC, QueryC, F>(init_fn: F) -> BasicApp<ExecC, QueryC>
111where
112 ExecC: CustomMsg + DeserializeOwned + 'static,
113 QueryC: Debug + CustomQuery + DeserializeOwned + 'static,
114 F: FnOnce(
115 &mut Router<
116 BankKeeper,
117 FailingModule<ExecC, QueryC, Empty>,
118 WasmKeeper<ExecC, QueryC>,
119 StakeKeeper,
120 DistributionKeeper,
121 IbcFailingModule,
122 GovFailingModule,
123 StargateFailingModule,
124 >,
125 &dyn Api,
126 &mut dyn Storage,
127 ),
128{
129 AppBuilder::new_custom().build(init_fn)
130}
131
132impl<BankT, ApiT, StorageT, CustomT, WasmT, StakingT, DistrT, IbcT, GovT, StargateT> Querier
133 for App<BankT, ApiT, StorageT, CustomT, WasmT, StakingT, DistrT, IbcT, GovT, StargateT>
134where
135 CustomT::ExecT: CustomMsg + DeserializeOwned + 'static,
136 CustomT::QueryT: CustomQuery + DeserializeOwned + 'static,
137 WasmT: Wasm<CustomT::ExecT, CustomT::QueryT>,
138 BankT: Bank,
139 ApiT: Api,
140 StorageT: Storage,
141 CustomT: Module,
142 StakingT: Staking,
143 DistrT: Distribution,
144 IbcT: Ibc,
145 GovT: Gov,
146 StargateT: Stargate,
147{
148 fn raw_query(&self, bin_request: &[u8]) -> QuerierResult {
149 self.router
150 .querier(&self.api, &self.storage, &self.block)
151 .raw_query(bin_request)
152 }
153}
154
155impl<BankT, ApiT, StorageT, CustomT, WasmT, StakingT, DistrT, IbcT, GovT, StargateT>
156 Executor<CustomT::ExecT>
157 for App<BankT, ApiT, StorageT, CustomT, WasmT, StakingT, DistrT, IbcT, GovT, StargateT>
158where
159 CustomT::ExecT: CustomMsg + DeserializeOwned + 'static,
160 CustomT::QueryT: CustomQuery + DeserializeOwned + 'static,
161 WasmT: Wasm<CustomT::ExecT, CustomT::QueryT>,
162 BankT: Bank,
163 ApiT: Api,
164 StorageT: Storage,
165 CustomT: Module,
166 StakingT: Staking,
167 DistrT: Distribution,
168 IbcT: Ibc,
169 GovT: Gov,
170 StargateT: Stargate,
171{
172 fn execute(&mut self, sender: Addr, msg: CosmosMsg<CustomT::ExecT>) -> AnyResult<AppResponse> {
173 let mut all = self.execute_multi(sender, vec![msg])?;
174 let res = all.pop().unwrap();
175 Ok(res)
176 }
177}
178
179impl<BankT, ApiT, StorageT, CustomT, WasmT, StakingT, DistrT, IbcT, GovT, StargateT>
180 App<BankT, ApiT, StorageT, CustomT, WasmT, StakingT, DistrT, IbcT, GovT, StargateT>
181where
182 WasmT: Wasm<CustomT::ExecT, CustomT::QueryT>,
183 BankT: Bank,
184 ApiT: Api,
185 StorageT: Storage,
186 CustomT: Module,
187 StakingT: Staking,
188 DistrT: Distribution,
189 IbcT: Ibc,
190 GovT: Gov,
191 StargateT: Stargate,
192{
193 pub fn router(
195 &self,
196 ) -> &Router<BankT, CustomT, WasmT, StakingT, DistrT, IbcT, GovT, StargateT> {
197 &self.router
198 }
199
200 pub fn api(&self) -> &ApiT {
202 &self.api
203 }
204
205 pub fn storage(&self) -> &StorageT {
207 &self.storage
208 }
209
210 pub fn storage_mut(&mut self) -> &mut StorageT {
212 &mut self.storage
213 }
214
215 pub fn init_modules<F, T>(&mut self, init_fn: F) -> T
217 where
218 F: FnOnce(
219 &mut Router<BankT, CustomT, WasmT, StakingT, DistrT, IbcT, GovT, StargateT>,
220 &dyn Api,
221 &mut dyn Storage,
222 ) -> T,
223 {
224 init_fn(&mut self.router, &self.api, &mut self.storage)
225 }
226
227 pub fn read_module<F, T>(&self, query_fn: F) -> T
229 where
230 F: FnOnce(
231 &Router<BankT, CustomT, WasmT, StakingT, DistrT, IbcT, GovT, StargateT>,
232 &dyn Api,
233 &dyn Storage,
234 ) -> T,
235 {
236 query_fn(&self.router, &self.api, &self.storage)
237 }
238}
239
240impl<BankT, ApiT, StorageT, CustomT, WasmT, StakingT, DistrT, IbcT, GovT, StargateT>
243 App<BankT, ApiT, StorageT, CustomT, WasmT, StakingT, DistrT, IbcT, GovT, StargateT>
244where
245 BankT: Bank,
246 ApiT: Api,
247 StorageT: Storage,
248 CustomT: Module,
249 WasmT: Wasm<CustomT::ExecT, CustomT::QueryT>,
250 StakingT: Staking,
251 DistrT: Distribution,
252 IbcT: Ibc,
253 GovT: Gov,
254 StargateT: Stargate,
255 CustomT::ExecT: CustomMsg + DeserializeOwned + 'static,
256 CustomT::QueryT: CustomQuery + DeserializeOwned + 'static,
257{
258 pub fn store_code(&mut self, code: Box<dyn Contract<CustomT::ExecT, CustomT::QueryT>>) -> u64 {
261 self.router
262 .wasm
263 .store_code(MockApi::default().addr_make("creator"), code)
264 }
265
266 pub fn store_code_with_creator(
269 &mut self,
270 creator: Addr,
271 code: Box<dyn Contract<CustomT::ExecT, CustomT::QueryT>>,
272 ) -> u64 {
273 self.router.wasm.store_code(creator, code)
274 }
275
276 pub fn store_code_with_id(
279 &mut self,
280 creator: Addr,
281 code_id: u64,
282 code: Box<dyn Contract<CustomT::ExecT, CustomT::QueryT>>,
283 ) -> AnyResult<u64> {
284 self.router.wasm.store_code_with_id(creator, code_id, code)
285 }
286
287 pub fn duplicate_code(&mut self, code_id: u64) -> AnyResult<u64> {
337 self.router.wasm.duplicate_code(code_id)
338 }
339
340 pub fn contract_data(&self, address: &Addr) -> AnyResult<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.router
410 .staking
411 .process_queue(&self.api, &mut self.storage, &self.router, &self.block)
412 .unwrap();
413 self.block = block;
414 }
415
416 pub fn update_block<F: Fn(&mut BlockInfo)>(&mut self, action: F) {
418 self.router
419 .staking
420 .process_queue(&self.api, &mut self.storage, &self.router, &self.block)
421 .unwrap();
422 action(&mut self.block);
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 ) -> AnyResult<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 use_contract<
464 F: FnOnce(DepsMut<CustomT::QueryT>, Env) -> AnyResult<Response<CustomT::ExecT>>,
465 >(
466 &mut self,
467 contract_addr: &Addr,
468 action: F,
469 ) -> AnyResult<AppResponse> {
470 let Self {
471 api,
472 storage,
473 block,
474 router,
475 } = self;
476
477 transactional(&mut *storage, |write_cache, _| {
478 router.wasm.use_contract(
479 &*api,
480 write_cache,
481 router,
482 block,
483 contract_addr.clone(),
484 action,
485 )
486 })
487 }
488
489 pub fn use_parts(
491 &mut self,
492 ) -> (
493 &mut ApiT,
494 &mut StorageT,
495 &mut BlockInfo,
496 &mut Router<BankT, CustomT, WasmT, StakingT, DistrT, IbcT, GovT, StargateT>,
497 ) {
498 let Self {
499 api,
500 storage,
501 block,
502 router,
503 } = self;
504
505 (api, storage, block, router)
506 }
507
508 pub fn wasm_sudo<T: Serialize, U: Into<Addr>>(
512 &mut self,
513 contract_addr: U,
514 msg: &T,
515 ) -> AnyResult<AppResponse> {
516 let msg = WasmSudo {
517 contract_addr: contract_addr.into(),
518 message: to_json_binary(msg)?,
519 };
520
521 let Self {
522 block,
523 router,
524 api,
525 storage,
526 } = self;
527
528 transactional(&mut *storage, |write_cache, _| {
529 router.wasm.sudo(&*api, write_cache, router, block, msg)
530 })
531 }
532
533 pub fn sudo(&mut self, msg: SudoMsg) -> AnyResult<AppResponse> {
537 let Self {
541 block,
542 router,
543 api,
544 storage,
545 } = self;
546
547 transactional(&mut *storage, |write_cache, _| {
548 router.sudo(&*api, write_cache, block, msg)
549 })
550 }
551}
552#[derive(Clone)]
555pub struct Router<Bank, Custom, Wasm, Staking, Distr, Ibc, Gov, Stargate> {
556 pub(crate) wasm: Wasm,
558 pub bank: Bank,
560 pub custom: Custom,
562 pub staking: Staking,
564 pub distribution: Distr,
566 pub ibc: Ibc,
568 pub gov: Gov,
570 pub stargate: Stargate,
572}
573
574impl<BankT, CustomT, WasmT, StakingT, DistrT, IbcT, GovT, StargateT>
575 Router<BankT, CustomT, WasmT, StakingT, DistrT, IbcT, GovT, StargateT>
576where
577 CustomT::ExecT: CustomMsg + DeserializeOwned + 'static,
578 CustomT::QueryT: CustomQuery + DeserializeOwned + 'static,
579 CustomT: Module,
580 WasmT: Wasm<CustomT::ExecT, CustomT::QueryT>,
581 BankT: Bank,
582 StakingT: Staking,
583 DistrT: Distribution,
584 IbcT: Ibc,
585 GovT: Gov,
586 StargateT: Stargate,
587{
588 pub fn querier<'a>(
590 &'a self,
591 api: &'a dyn Api,
592 storage: &'a dyn Storage,
593 block_info: &'a BlockInfo,
594 ) -> RouterQuerier<'a, CustomT::ExecT, CustomT::QueryT> {
595 RouterQuerier {
596 router: self,
597 api,
598 storage,
599 block_info,
600 }
601 }
602}
603
604pub enum SudoMsg {
607 Bank(BankSudo),
609 Custom(Empty),
611 Staking(StakingSudo),
613 Wasm(WasmSudo),
615}
616
617impl From<WasmSudo> for SudoMsg {
618 fn from(wasm: WasmSudo) -> Self {
619 SudoMsg::Wasm(wasm)
620 }
621}
622
623impl From<BankSudo> for SudoMsg {
624 fn from(bank: BankSudo) -> Self {
625 SudoMsg::Bank(bank)
626 }
627}
628
629impl From<StakingSudo> for SudoMsg {
630 fn from(staking: StakingSudo) -> Self {
631 SudoMsg::Staking(staking)
632 }
633}
634pub trait CosmosRouter {
640 type ExecC: CustomMsg;
642 type QueryC: CustomQuery;
644
645 fn execute(
647 &self,
648 api: &dyn Api,
649 storage: &mut dyn Storage,
650 block: &BlockInfo,
651 sender: Addr,
652 msg: CosmosMsg<Self::ExecC>,
653 ) -> AnyResult<AppResponse>;
654
655 fn query(
657 &self,
658 api: &dyn Api,
659 storage: &dyn Storage,
660 block: &BlockInfo,
661 request: QueryRequest<Self::QueryC>,
662 ) -> AnyResult<Binary>;
663
664 fn sudo(
666 &self,
667 api: &dyn Api,
668 storage: &mut dyn Storage,
669 block: &BlockInfo,
670 msg: SudoMsg,
671 ) -> AnyResult<AppResponse>;
672}
673
674impl<BankT, CustomT, WasmT, StakingT, DistrT, IbcT, GovT, StargateT> CosmosRouter
675 for Router<BankT, CustomT, WasmT, StakingT, DistrT, IbcT, GovT, StargateT>
676where
677 CustomT::ExecT: CustomMsg + DeserializeOwned + 'static,
678 CustomT::QueryT: CustomQuery + DeserializeOwned + 'static,
679 CustomT: Module,
680 WasmT: Wasm<CustomT::ExecT, CustomT::QueryT>,
681 BankT: Bank,
682 StakingT: Staking,
683 DistrT: Distribution,
684 IbcT: Ibc,
685 GovT: Gov,
686 StargateT: Stargate,
687{
688 type ExecC = CustomT::ExecT;
689 type QueryC = CustomT::QueryT;
690
691 fn execute(
692 &self,
693 api: &dyn Api,
694 storage: &mut dyn Storage,
695 block: &BlockInfo,
696 sender: Addr,
697 msg: CosmosMsg<Self::ExecC>,
698 ) -> AnyResult<AppResponse> {
699 match msg {
700 CosmosMsg::Wasm(msg) => self.wasm.execute(api, storage, self, block, sender, msg),
701 CosmosMsg::Bank(msg) => self.bank.execute(api, storage, self, block, sender, msg),
702 CosmosMsg::Custom(msg) => self.custom.execute(api, storage, self, block, sender, msg),
703 CosmosMsg::Staking(msg) => self.staking.execute(api, storage, self, block, sender, msg),
704 CosmosMsg::Distribution(msg) => self
705 .distribution
706 .execute(api, storage, self, block, sender, msg),
707 CosmosMsg::Ibc(msg) => self.ibc.execute(api, storage, self, block, sender, msg),
708 CosmosMsg::Gov(msg) => self.gov.execute(api, storage, self, block, sender, msg),
709 CosmosMsg::Any(msg) => self
710 .stargate
711 .execute(api, storage, self, block, sender, msg),
712 _ => bail!("Cannot execute {:?}", msg),
713 }
714 }
715
716 fn query(
720 &self,
721 api: &dyn Api,
722 storage: &dyn Storage,
723 block: &BlockInfo,
724 request: QueryRequest<Self::QueryC>,
725 ) -> AnyResult<Binary> {
726 let querier = self.querier(api, storage, block);
727 match request {
728 QueryRequest::Wasm(req) => self.wasm.query(api, storage, &querier, block, req),
729 QueryRequest::Bank(req) => self.bank.query(api, storage, &querier, block, req),
730 QueryRequest::Custom(req) => self.custom.query(api, storage, &querier, block, req),
731 QueryRequest::Staking(req) => self.staking.query(api, storage, &querier, block, req),
732 QueryRequest::Ibc(req) => self.ibc.query(api, storage, &querier, block, req),
733 QueryRequest::Grpc(req) => self.stargate.query(api, storage, &querier, block, req),
734 _ => unimplemented!(),
735 }
736 }
737
738 fn sudo(
739 &self,
740 api: &dyn Api,
741 storage: &mut dyn Storage,
742 block: &BlockInfo,
743 msg: SudoMsg,
744 ) -> AnyResult<AppResponse> {
745 match msg {
746 SudoMsg::Wasm(msg) => self.wasm.sudo(api, storage, self, block, msg),
747 SudoMsg::Bank(msg) => self.bank.sudo(api, storage, self, block, msg),
748 SudoMsg::Staking(msg) => self.staking.sudo(api, storage, self, block, msg),
749 SudoMsg::Custom(_) => unimplemented!(),
750 }
751 }
752}
753
754pub struct MockRouter<ExecC, QueryC>(PhantomData<(ExecC, QueryC)>);
755
756impl Default for MockRouter<Empty, Empty> {
757 fn default() -> Self {
758 Self::new()
759 }
760}
761
762impl<ExecC, QueryC> MockRouter<ExecC, QueryC> {
763 pub fn new() -> Self
764 where
765 QueryC: CustomQuery,
766 {
767 MockRouter(PhantomData)
768 }
769}
770
771impl<ExecC, QueryC> CosmosRouter for MockRouter<ExecC, QueryC>
772where
773 ExecC: CustomMsg,
774 QueryC: CustomQuery,
775{
776 type ExecC = ExecC;
777 type QueryC = QueryC;
778
779 fn execute(
780 &self,
781 _api: &dyn Api,
782 _storage: &mut dyn Storage,
783 _block: &BlockInfo,
784 _sender: Addr,
785 _msg: CosmosMsg<Self::ExecC>,
786 ) -> AnyResult<AppResponse> {
787 panic!("Cannot execute MockRouters");
788 }
789
790 fn query(
791 &self,
792 _api: &dyn Api,
793 _storage: &dyn Storage,
794 _block: &BlockInfo,
795 _request: QueryRequest<Self::QueryC>,
796 ) -> AnyResult<Binary> {
797 panic!("Cannot query MockRouters");
798 }
799
800 fn sudo(
801 &self,
802 _api: &dyn Api,
803 _storage: &mut dyn Storage,
804 _block: &BlockInfo,
805 _msg: SudoMsg,
806 ) -> AnyResult<AppResponse> {
807 panic!("Cannot sudo MockRouters");
808 }
809}
810
811pub struct RouterQuerier<'a, ExecC, QueryC> {
812 router: &'a dyn CosmosRouter<ExecC = ExecC, QueryC = QueryC>,
813 api: &'a dyn Api,
814 storage: &'a dyn Storage,
815 block_info: &'a BlockInfo,
816}
817
818impl<'a, ExecC, QueryC> RouterQuerier<'a, ExecC, QueryC> {
819 pub fn new(
820 router: &'a dyn CosmosRouter<ExecC = ExecC, QueryC = QueryC>,
821 api: &'a dyn Api,
822 storage: &'a dyn Storage,
823 block_info: &'a BlockInfo,
824 ) -> Self {
825 Self {
826 router,
827 api,
828 storage,
829 block_info,
830 }
831 }
832}
833
834impl<'a, ExecC, QueryC> Querier for RouterQuerier<'a, ExecC, QueryC>
835where
836 ExecC: CustomMsg + DeserializeOwned + 'static,
837 QueryC: CustomQuery + DeserializeOwned + 'static,
838{
839 fn raw_query(&self, bin_request: &[u8]) -> QuerierResult {
840 let request: QueryRequest<QueryC> = match from_json(bin_request) {
841 Ok(v) => v,
842 Err(e) => {
843 return SystemResult::Err(SystemError::InvalidRequest {
844 error: format!("Parsing query request: {}", e),
845 request: bin_request.into(),
846 })
847 }
848 };
849 let contract_result: ContractResult<Binary> = self
850 .router
851 .query(self.api, self.storage, self.block_info, request)
852 .into();
853 SystemResult::Ok(contract_result)
854 }
855}