From 19071df153e8ebb66ff1b929fa1c93fcf4714ce0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Kuras?= Date: Mon, 13 Sep 2021 15:06:25 +0200 Subject: [PATCH] Abstracting out Storage in multitest App, clippization --- packages/multi-test/src/app.rs | 151 ++++++++++++++-------- packages/multi-test/src/custom_handler.rs | 6 + 2 files changed, 105 insertions(+), 52 deletions(-) diff --git a/packages/multi-test/src/app.rs b/packages/multi-test/src/app.rs index 217329c78..93fb30ba2 100644 --- a/packages/multi-test/src/app.rs +++ b/packages/multi-test/src/app.rs @@ -26,8 +26,13 @@ pub fn next_block(block: &mut BlockInfo) { } /// Type alias for default build `App` to make its storing simpler in typical scenario -pub type BasicApp = - App, WasmKeeper>; +pub type BasicApp = App< + BankKeeper, + MockApi, + MockStorage, + PanickingCustomHandler, + WasmKeeper, +>; /// Router is a persisted state. You can query this. /// Execution generally happens on the RouterCache, which then can be atomically committed or rolled back. @@ -35,15 +40,22 @@ pub type BasicApp = pub struct App< Bank = BankKeeper, Api = MockApi, + Storage = MockStorage, Custom = PanickingCustomHandler, Wasm = WasmKeeper, > { router: Router, api: Api, - storage: Box, + storage: Storage, block: BlockInfo, } +impl Default for BasicApp { + fn default() -> Self { + Self::new() + } +} + impl BasicApp { /// Creates new default `App` implementation working with Empty custom messages. pub fn new() -> Self { @@ -61,29 +73,32 @@ where AppBuilder::new_custom().build() } -impl Querier for App +impl Querier for App where CustomT::ExecC: Clone + fmt::Debug + PartialEq + JsonSchema + DeserializeOwned + 'static, CustomT::QueryC: CustomQuery + DeserializeOwned + 'static, WasmT: Wasm, BankT: Bank, ApiT: Api, + StorageT: Storage, CustomT: CustomHandler, { fn raw_query(&self, bin_request: &[u8]) -> QuerierResult { self.router - .querier(&self.api, &*self.storage, &self.block) + .querier(&self.api, &self.storage, &self.block) .raw_query(bin_request) } } -impl Executor for App +impl Executor + for App where CustomT::ExecC: Clone + fmt::Debug + PartialEq + JsonSchema + DeserializeOwned + 'static, CustomT::QueryC: CustomQuery + DeserializeOwned + 'static, WasmT: Wasm, BankT: Bank, ApiT: Api, + StorageT: Storage, CustomT: CustomHandler, { fn execute(&mut self, sender: Addr, msg: CosmosMsg) -> AnyResult { @@ -94,17 +109,37 @@ where } /// Utility to build App in stages. If particular items wont be set, defaults would be used -pub struct AppBuilder { +pub struct AppBuilder { wasm: Wasm, bank: Bank, api: Api, - storage: Option>, + storage: Storage, custom: Custom, - block: Option, + block: BlockInfo, +} + +impl Default + for AppBuilder< + BankKeeper, + MockApi, + MockStorage, + PanickingCustomHandler, + WasmKeeper, + > +{ + fn default() -> Self { + Self::new() + } } impl - AppBuilder, WasmKeeper> + AppBuilder< + BankKeeper, + MockApi, + MockStorage, + PanickingCustomHandler, + WasmKeeper, + > { /// Creates builder with default components working with empty exec and query messages. pub fn new() -> Self { @@ -112,9 +147,9 @@ impl wasm: WasmKeeper::new(), bank: BankKeeper::new(), api: MockApi::default(), - storage: None, + storage: MockStorage::new(), custom: PanickingCustomHandler::new(), - block: None, + block: mock_env().block, } } } @@ -123,6 +158,7 @@ impl AppBuilder< BankKeeper, MockApi, + MockStorage, PanickingCustomHandler, WasmKeeper, > @@ -137,14 +173,14 @@ where wasm: WasmKeeper::new(), bank: BankKeeper::new(), api: MockApi::default(), - storage: None, + storage: MockStorage::new(), custom: PanickingCustomHandler::new(), - block: None, + block: mock_env().block, } } } -impl AppBuilder { +impl AppBuilder { /// Overwrites default wasm executor. /// /// At this point it is needed that new wasm implements some `Wasm` trait, but it doesn't need @@ -157,7 +193,7 @@ impl AppBuilder { pub fn with_wasm>( self, wasm: NewWasm, - ) -> AppBuilder { + ) -> AppBuilder { let AppBuilder { bank, api, @@ -181,7 +217,7 @@ impl AppBuilder { pub fn with_bank( self, bank: NewBank, - ) -> AppBuilder { + ) -> AppBuilder { let AppBuilder { wasm, api, @@ -202,7 +238,10 @@ impl AppBuilder { } /// Overwrites default api interface - pub fn with_api(self, api: NewApi) -> AppBuilder { + pub fn with_api( + self, + api: NewApi, + ) -> AppBuilder { let AppBuilder { wasm, bank, @@ -223,14 +262,27 @@ impl AppBuilder { } /// Overwrites default storage interface - #[track_caller] - pub fn with_storage(mut self, storage: impl Storage + 'static) -> Self { - assert!( - self.storage.is_none(), - "Storage interface already overwritten" - ); - self.storage = Some(Box::new(storage)); - self + pub fn with_storage( + self, + storage: NewStorage, + ) -> AppBuilder { + let AppBuilder { + wasm, + api, + bank, + custom, + block, + .. + } = self; + + AppBuilder { + wasm, + bank, + api, + storage, + custom, + block, + } } /// Overwrites default custom messages handler @@ -245,7 +297,7 @@ impl AppBuilder { pub fn with_custom( self, custom: NewCustom, - ) -> AppBuilder { + ) -> AppBuilder { let AppBuilder { wasm, bank, @@ -266,30 +318,22 @@ impl AppBuilder { } /// Overwrites default initial block - #[track_caller] pub fn with_block(mut self, block: BlockInfo) -> Self { - assert!( - self.block.is_none(), - "Initial block info already overwritten" - ); - self.block = Some(block); + self.block = block; self } /// Builds final `App`. At this point all components type have to be properly related to each /// other. If there are some generics related compilation error make sure, that all components /// are properly relating to each other. - pub fn build(self) -> App + pub fn build(self) -> App where BankT: Bank, ApiT: Api, + StorageT: Storage, CustomT: CustomHandler, WasmT: Wasm, { - let api = self.api; - let storage = self.storage.unwrap_or_else(|| Box::new(MockStorage::new())); - let block = self.block.unwrap_or_else(|| mock_env().block); - let router = Router { wasm: self.wasm, bank: self.bank, @@ -298,20 +342,21 @@ impl AppBuilder { App { router, - api, - storage, - block, + api: self.api, + storage: self.storage, + block: self.block, } } } -impl App +impl App where CustomT::ExecC: std::fmt::Debug + PartialEq + Clone + JsonSchema + DeserializeOwned + 'static, CustomT::QueryC: CustomQuery + DeserializeOwned + 'static, WasmT: Wasm, BankT: Bank, ApiT: Api, + StorageT: Storage, CustomT: CustomHandler, { pub fn set_block(&mut self, block: BlockInfo) { @@ -353,7 +398,7 @@ where storage, } = self; - transactional(&mut **storage, |write_cache, _| { + transactional(&mut *storage, |write_cache, _| { msgs.into_iter() .map(|msg| router.execute(&*api, write_cache, block, sender.clone(), msg)) .collect() @@ -364,7 +409,7 @@ where pub fn init_bank_balance(&mut self, account: &Addr, amount: Vec) -> AnyResult<()> { self.router .bank - .init_balance(&mut *self.storage, account, amount) + .init_balance(&mut self.storage, account, amount) } /// This registers contract code (like uploading wasm bytecode on a chain), @@ -375,7 +420,7 @@ where /// This allows to get `ContractData` for specific contract pub fn contract_data(&self, address: &Addr) -> AnyResult { - self.router.wasm.contract_data(&*self.storage, address) + self.router.wasm.contract_data(&self.storage, address) } /// Runs arbitrary CosmosMsg in "sudo" mode. @@ -390,7 +435,7 @@ where self.router.wasm.sudo( &self.api, contract_addr.into(), - &mut *self.storage, + &mut self.storage, &self.router, &self.block, msg, @@ -535,8 +580,8 @@ mod test { use super::*; - fn get_balance( - app: &App, + fn get_balance( + app: &App, addr: &Addr, ) -> Vec where @@ -545,6 +590,7 @@ mod test { WasmT: Wasm, BankT: Bank, ApiT: Api, + StorageT: Storage, CustomT: CustomHandler, { app.wrap().query_all_balances(addr).unwrap() @@ -1009,8 +1055,8 @@ mod test { val.amount } - fn query_app( - app: &App, + fn query_app( + app: &App, rcpt: &Addr, ) -> Vec where @@ -1020,6 +1066,7 @@ mod test { WasmT: Wasm, BankT: Bank, ApiT: Api, + StorageT: Storage, CustomT: CustomHandler, { let query = BankQuery::AllBalances { @@ -1041,7 +1088,7 @@ mod test { app.init_bank_balance(&owner, init_funds).unwrap(); // cache 1 - send some tokens - let mut cache = StorageTransaction::new(&*app.storage); + let mut cache = StorageTransaction::new(&app.storage); let msg = BankMsg::Send { to_address: rcpt.clone().into(), amount: coins(25, "eth"), @@ -1076,7 +1123,7 @@ mod test { .unwrap(); // apply first to router - cache.prepare().commit(&mut *app.storage); + cache.prepare().commit(&mut app.storage); let committed = query_app(&app, &rcpt); assert_eq!(coins(37, "eth"), committed); diff --git a/packages/multi-test/src/custom_handler.rs b/packages/multi-test/src/custom_handler.rs index 88019fe54..f3420806f 100644 --- a/packages/multi-test/src/custom_handler.rs +++ b/packages/multi-test/src/custom_handler.rs @@ -46,6 +46,12 @@ impl PanickingCustomHandler { } } +impl Default for PanickingCustomHandler { + fn default() -> Self { + Self::new() + } +} + impl CustomHandler for PanickingCustomHandler where Exec: std::fmt::Debug,