From 0f86c02e331f7fabe66427d5db8cf131b3fdc67a Mon Sep 17 00:00:00 2001 From: CyberHoward <88450409+CyberHoward@users.noreply.github.com> Date: Tue, 28 Nov 2023 15:08:30 +0100 Subject: [PATCH] Add WasmCodeQuerier support to ForkMock (#277) * Add `WasmCodeQuerier` to `CwEnv` trait bound * update conditional trait's bounds * update ConditionalMigrate impl trait bound * update changelog * Added contact code querier for osmosis test tube * Format * fix clippy --------- Co-authored-by: Kayanski --- CHANGELOG.md | 4 + .../examples/daemon-capabilities.rs | 8 +- cw-orch-daemon/src/traits.rs | 4 +- cw-orch/Cargo.toml | 1 + cw-orch/src/osmosis_test_tube/core.rs | 96 +++++++++++++++++++ .../src/contract/interface_traits.rs | 10 +- .../src/environment/cosmwasm_environment.rs | 10 +- packages/cw-orch-mock/Cargo.toml | 2 +- packages/cw-orch-mock/src/core.rs | 4 +- 9 files changed, 120 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f88055dfc..50ea4891f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # cw-orchestrator Changelog +## Unreleased + +- Add `WasmCodeQuerier` as trait bound to `CwEnv`. + ## 0.18.2 - Added Snapshot-Testing diff --git a/cw-orch-daemon/examples/daemon-capabilities.rs b/cw-orch-daemon/examples/daemon-capabilities.rs index ed3ca7466..5c1ccc09d 100644 --- a/cw-orch-daemon/examples/daemon-capabilities.rs +++ b/cw-orch-daemon/examples/daemon-capabilities.rs @@ -26,16 +26,16 @@ pub fn main() -> anyhow::Result<()> { // ANCHOR: cosmrs_tx let tx_msg = cosmrs::staking::MsgBeginRedelegate { - /// Delegator's address. + // Delegator's address. delegator_address: AccountId::from_str("").unwrap(), - /// Source validator's address. + // Source validator's address. validator_src_address: AccountId::from_str("").unwrap(), - /// Destination validator's address. + // Destination validator's address. validator_dst_address: AccountId::from_str("").unwrap(), - /// Amount to UnDelegate + // Amount to UnDelegate amount: Coin { amount: 100_000_000_000_000u128, denom: Denom::from_str("ujuno").unwrap(), diff --git a/cw-orch-daemon/src/traits.rs b/cw-orch-daemon/src/traits.rs index 668e11b98..cfb59505f 100644 --- a/cw-orch-daemon/src/traits.rs +++ b/cw-orch-daemon/src/traits.rs @@ -1,6 +1,6 @@ use crate::{queriers::CosmWasm, Daemon, DaemonError}; use cosmwasm_std::ContractInfoResponse; -use cw_orch_core::{contract::interface_traits::CwOrchUpload, environment::WasmCodeQuerier}; +use cw_orch_core::{contract::interface_traits::ContractInstance, environment::WasmCodeQuerier}; impl WasmCodeQuerier for Daemon { /// Returns the checksum of provided code_id @@ -12,7 +12,7 @@ impl WasmCodeQuerier for Daemon { } /// Returns the code_info structure of the provided contract - fn contract_info>( + fn contract_info>( &self, contract: &T, ) -> Result { diff --git a/cw-orch/Cargo.toml b/cw-orch/Cargo.toml index b48d0c716..1a38f97b6 100644 --- a/cw-orch/Cargo.toml +++ b/cw-orch/Cargo.toml @@ -97,6 +97,7 @@ cw-orch-mock = { workspace = true } # Snapshot deps insta = { version = "1.34.0", features = ["yaml"], optional = true } sanitize-filename = "0.5.0" +hex = "0.4.3" [dev-dependencies] cw-orch = { features = ["daemon", "snapshot-testing"], path = "." } diff --git a/cw-orch/src/osmosis_test_tube/core.rs b/cw-orch/src/osmosis_test_tube/core.rs index 28cf07c1a..182e26140 100644 --- a/cw-orch/src/osmosis_test_tube/core.rs +++ b/cw-orch/src/osmosis_test_tube/core.rs @@ -1,9 +1,15 @@ use crate::contract::WasmPath; use crate::prelude::Uploadable; +use cosmwasm_std::ContractInfoResponse; +use cw_orch_core::environment::WasmCodeQuerier; use cw_orch_traits::stargate::Stargate; use cosmwasm_std::{Binary, BlockInfo, Coin, Timestamp, Uint128}; use cw_multi_test::AppResponse; +use osmosis_std::types::cosmwasm::wasm::v1::QueryCodeRequest; +use osmosis_std::types::cosmwasm::wasm::v1::QueryCodeResponse; +use osmosis_std::types::cosmwasm::wasm::v1::QueryContractInfoRequest; +use osmosis_std::types::cosmwasm::wasm::v1::QueryContractInfoResponse; use osmosis_test_tube::Account; use osmosis_test_tube::Bank; use osmosis_test_tube::ExecuteResponse; @@ -338,3 +344,93 @@ impl Stargate for OsmosisTestTube { }) } } + +impl WasmCodeQuerier for OsmosisTestTube { + fn contract_hash(&self, code_id: u64) -> Result::Error> { + let code_info_result: QueryCodeResponse = self + .app + .borrow() + .query( + "/cosmwasm.wasm.v1.Query/Code", + &QueryCodeRequest { code_id }, + ) + .map_err(map_err)?; + + Ok(hex::encode( + code_info_result + .code_info + .ok_or(CwOrchError::CodeIdNotInStore(code_id.to_string()))? + .data_hash, + )) + } + + fn contract_info>( + &self, + contract: &T, + ) -> Result::Error> { + let result = self + .app + .borrow() + .query::<_, QueryContractInfoResponse>( + "/cosmwasm.wasm.v1.Query/ContractInfo", + &QueryContractInfoRequest { + address: contract.address()?.to_string(), + }, + ) + .map_err(map_err)? + .contract_info + .ok_or(CwOrchError::AddrNotInStore(contract.address()?.to_string()))?; + + let mut contract_info = ContractInfoResponse::default(); + contract_info.code_id = result.code_id; + contract_info.creator = result.creator; + contract_info.admin = Some(result.admin); + + contract_info.ibc_port = if result.ibc_port_id.is_empty() { + None + } else { + Some(result.ibc_port_id) + }; + + Ok(contract_info) + } +} + +#[cfg(test)] +pub mod tests { + use cosmwasm_std::{coins, ContractInfoResponse}; + use cw_orch_core::environment::WasmCodeQuerier; + use osmosis_test_tube::Account; + + use super::OsmosisTestTube; + use counter_contract::{msg::InstantiateMsg, CounterContract}; + use cw_orch::prelude::*; + + #[test] + fn wasm_querier_works() -> anyhow::Result<()> { + let app = OsmosisTestTube::new(coins(100_000_000_000_000, "uosmo")); + + let contract = CounterContract::new("counter", app.clone()); + contract.upload()?; + contract.instantiate( + &InstantiateMsg { count: 7 }, + Some(&Addr::unchecked(app.sender.address())), + None, + )?; + + assert_eq!( + contract.wasm().checksum()?, + app.contract_hash(contract.code_id()?)? + ); + + let contract_info = app.contract_info(&contract)?; + let mut target_contract_info = ContractInfoResponse::default(); + target_contract_info.admin = Some(app.sender.address().to_string()); + target_contract_info.code_id = contract.code_id()?; + target_contract_info.creator = app.sender.address().to_string(); + target_contract_info.ibc_port = None; + assert_eq!(contract_info, target_contract_info); + + Ok(()) + } +} diff --git a/packages/cw-orch-core/src/contract/interface_traits.rs b/packages/cw-orch-core/src/contract/interface_traits.rs index 708a64c81..9a2db7214 100644 --- a/packages/cw-orch-core/src/contract/interface_traits.rs +++ b/packages/cw-orch-core/src/contract/interface_traits.rs @@ -1,6 +1,6 @@ use super::{Contract, WasmPath}; use crate::{ - environment::{CwEnv, TxHandler, TxResponse, WasmCodeQuerier}, + environment::{CwEnv, TxHandler, TxResponse}, error::CwEnvError, log::CONTRACT_LOGS, }; @@ -197,7 +197,7 @@ pub trait CallAs: CwOrchExecute + ContractInstance + impl + ContractInstance + Clone, Chain: CwEnv> CallAs for T {} /// Helper methods for conditional uploading of a contract. -pub trait ConditionalUpload: CwOrchUpload { +pub trait ConditionalUpload: CwOrchUpload { /// Only upload the contract if it is not uploaded yet (checksum does not match) fn upload_if_needed(&self) -> Result>, CwEnvError> { if self.latest_is_uploaded()? { @@ -232,10 +232,10 @@ pub trait ConditionalUpload: CwOrchUpload { } } -impl ConditionalUpload for T where T: CwOrchUpload {} +impl ConditionalUpload for T where T: CwOrchUpload {} /// Helper methods for conditional migration of a contract. -pub trait ConditionalMigrate: +pub trait ConditionalMigrate: CwOrchMigrate + ConditionalUpload { /// Only migrate the contract if it is not on the latest code-id yet @@ -275,7 +275,7 @@ pub trait ConditionalMigrate: } } } -impl ConditionalMigrate for T where +impl ConditionalMigrate for T where T: CwOrchMigrate + ConditionalUpload { } diff --git a/packages/cw-orch-core/src/environment/cosmwasm_environment.rs b/packages/cw-orch-core/src/environment/cosmwasm_environment.rs index 456fdb954..81bf48735 100644 --- a/packages/cw-orch-core/src/environment/cosmwasm_environment.rs +++ b/packages/cw-orch-core/src/environment/cosmwasm_environment.rs @@ -2,7 +2,7 @@ use super::{ChainState, IndexResponse}; use crate::{ - contract::interface_traits::{CwOrchUpload, Uploadable}, + contract::interface_traits::{ContractInstance, Uploadable}, error::CwEnvError, }; use cosmwasm_std::{Addr, BlockInfo, Coin, ContractInfoResponse}; @@ -10,8 +10,8 @@ use serde::{de::DeserializeOwned, Serialize}; use std::fmt::Debug; /// Signals a supported execution environment for CosmWasm contracts -pub trait CwEnv: TxHandler + Clone {} -impl CwEnv for T {} +pub trait CwEnv: TxHandler + WasmCodeQuerier + Clone {} +impl CwEnv for T {} /// Response type for actions on an environment pub type TxResponse = ::Response; @@ -92,11 +92,11 @@ pub trait TxHandler: ChainState + Clone { } } -pub trait WasmCodeQuerier: CwEnv { +pub trait WasmCodeQuerier: TxHandler + Clone { /// Returns the checksum of provided code_id fn contract_hash(&self, code_id: u64) -> Result::Error>; /// Returns the code_info structure of the provided contract - fn contract_info>( + fn contract_info>( &self, contract: &T, ) -> Result::Error>; diff --git a/packages/cw-orch-mock/Cargo.toml b/packages/cw-orch-mock/Cargo.toml index 204668943..bff8abfbf 100644 --- a/packages/cw-orch-mock/Cargo.toml +++ b/packages/cw-orch-mock/Cargo.toml @@ -23,4 +23,4 @@ cw20-base = { workspace = true } mock-contract = { path = "../../contracts/mock_contract", features = [ "interface", -] } \ No newline at end of file +] } diff --git a/packages/cw-orch-mock/src/core.rs b/packages/cw-orch-mock/src/core.rs index 3581da20c..806d7cafe 100644 --- a/packages/cw-orch-mock/src/core.rs +++ b/packages/cw-orch-mock/src/core.rs @@ -6,7 +6,7 @@ use cw_utils::NativeBalance; use serde::{de::DeserializeOwned, Serialize}; use cw_orch_core::{ - contract::interface_traits::{CwOrchUpload, Uploadable}, + contract::interface_traits::{ContractInstance, Uploadable}, environment::{ChainState, IndexResponse, StateInterface}, environment::{TxHandler, WasmCodeQuerier}, CwEnvError, @@ -320,7 +320,7 @@ impl WasmCodeQuerier for Mock { } /// Returns the code_info structure of the provided contract - fn contract_info>( + fn contract_info>( &self, contract: &T, ) -> Result {