Skip to content

Commit

Permalink
Add WasmCodeQuerier support to ForkMock (#277)
Browse files Browse the repository at this point in the history
* 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 <kowalski.kowalskin@gmail.com>
  • Loading branch information
CyberHoward and Kayanski authored Nov 28, 2023
1 parent 752ad63 commit 0f86c02
Show file tree
Hide file tree
Showing 9 changed files with 120 additions and 19 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# cw-orchestrator Changelog

## Unreleased

- Add `WasmCodeQuerier` as trait bound to `CwEnv`.

## 0.18.2

- Added Snapshot-Testing
Expand Down
8 changes: 4 additions & 4 deletions cw-orch-daemon/examples/daemon-capabilities.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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("<my-address>").unwrap(),

/// Source validator's address.
// Source validator's address.
validator_src_address: AccountId::from_str("<my-least-favorite-validator>").unwrap(),

/// Destination validator's address.
// Destination validator's address.
validator_dst_address: AccountId::from_str("<my-favorite-validator>").unwrap(),

/// Amount to UnDelegate
// Amount to UnDelegate
amount: Coin {
amount: 100_000_000_000_000u128,
denom: Denom::from_str("ujuno").unwrap(),
Expand Down
4 changes: 2 additions & 2 deletions cw-orch-daemon/src/traits.rs
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -12,7 +12,7 @@ impl WasmCodeQuerier for Daemon {
}

/// Returns the code_info structure of the provided contract
fn contract_info<T: CwOrchUpload<Self>>(
fn contract_info<T: ContractInstance<Self>>(
&self,
contract: &T,
) -> Result<ContractInfoResponse, DaemonError> {
Expand Down
1 change: 1 addition & 0 deletions cw-orch/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 = "." }
Expand Down
96 changes: 96 additions & 0 deletions cw-orch/src/osmosis_test_tube/core.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -338,3 +344,93 @@ impl Stargate for OsmosisTestTube {
})
}
}

impl WasmCodeQuerier for OsmosisTestTube {
fn contract_hash(&self, code_id: u64) -> Result<String, <Self as TxHandler>::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<T: cw_orch_core::contract::interface_traits::ContractInstance<Self>>(
&self,
contract: &T,
) -> Result<cosmwasm_std::ContractInfoResponse, <Self as TxHandler>::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(())
}
}
10 changes: 5 additions & 5 deletions packages/cw-orch-core/src/contract/interface_traits.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::{Contract, WasmPath};
use crate::{
environment::{CwEnv, TxHandler, TxResponse, WasmCodeQuerier},
environment::{CwEnv, TxHandler, TxResponse},
error::CwEnvError,
log::CONTRACT_LOGS,
};
Expand Down Expand Up @@ -197,7 +197,7 @@ pub trait CallAs<Chain: CwEnv>: CwOrchExecute<Chain> + ContractInstance<Chain> +
impl<T: CwOrchExecute<Chain> + ContractInstance<Chain> + Clone, Chain: CwEnv> CallAs<Chain> for T {}

/// Helper methods for conditional uploading of a contract.
pub trait ConditionalUpload<Chain: WasmCodeQuerier>: CwOrchUpload<Chain> {
pub trait ConditionalUpload<Chain: CwEnv>: CwOrchUpload<Chain> {
/// Only upload the contract if it is not uploaded yet (checksum does not match)
fn upload_if_needed(&self) -> Result<Option<TxResponse<Chain>>, CwEnvError> {
if self.latest_is_uploaded()? {
Expand Down Expand Up @@ -232,10 +232,10 @@ pub trait ConditionalUpload<Chain: WasmCodeQuerier>: CwOrchUpload<Chain> {
}
}

impl<T, Chain: WasmCodeQuerier> ConditionalUpload<Chain> for T where T: CwOrchUpload<Chain> {}
impl<T, Chain: CwEnv> ConditionalUpload<Chain> for T where T: CwOrchUpload<Chain> {}

/// Helper methods for conditional migration of a contract.
pub trait ConditionalMigrate<Chain: WasmCodeQuerier>:
pub trait ConditionalMigrate<Chain: CwEnv>:
CwOrchMigrate<Chain> + ConditionalUpload<Chain>
{
/// Only migrate the contract if it is not on the latest code-id yet
Expand Down Expand Up @@ -275,7 +275,7 @@ pub trait ConditionalMigrate<Chain: WasmCodeQuerier>:
}
}
}
impl<T, Chain: WasmCodeQuerier> ConditionalMigrate<Chain> for T where
impl<T, Chain: CwEnv> ConditionalMigrate<Chain> for T where
T: CwOrchMigrate<Chain> + ConditionalUpload<Chain>
{
}
10 changes: 5 additions & 5 deletions packages/cw-orch-core/src/environment/cosmwasm_environment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@
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};
use serde::{de::DeserializeOwned, Serialize};
use std::fmt::Debug;

/// Signals a supported execution environment for CosmWasm contracts
pub trait CwEnv: TxHandler + Clone {}
impl<T: TxHandler + Clone> CwEnv for T {}
pub trait CwEnv: TxHandler + WasmCodeQuerier + Clone {}
impl<T: TxHandler + WasmCodeQuerier + Clone> CwEnv for T {}

/// Response type for actions on an environment
pub type TxResponse<Chain> = <Chain as TxHandler>::Response;
Expand Down Expand Up @@ -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<String, <Self as TxHandler>::Error>;
/// Returns the code_info structure of the provided contract
fn contract_info<T: CwOrchUpload<Self>>(
fn contract_info<T: ContractInstance<Self>>(
&self,
contract: &T,
) -> Result<ContractInfoResponse, <Self as TxHandler>::Error>;
Expand Down
2 changes: 1 addition & 1 deletion packages/cw-orch-mock/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@ cw20-base = { workspace = true }

mock-contract = { path = "../../contracts/mock_contract", features = [
"interface",
] }
] }
4 changes: 2 additions & 2 deletions packages/cw-orch-mock/src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -320,7 +320,7 @@ impl WasmCodeQuerier for Mock {
}

/// Returns the code_info structure of the provided contract
fn contract_info<T: CwOrchUpload<Self>>(
fn contract_info<T: ContractInstance<Self>>(
&self,
contract: &T,
) -> Result<ContractInfoResponse, CwEnvError> {
Expand Down

0 comments on commit 0f86c02

Please sign in to comment.