Skip to content

Commit

Permalink
Merge pull request #2217 from CosmWasm/match-MockApi-mock_env
Browse files Browse the repository at this point in the history
Let mock_env return a contract address that is compatible with MockApi
  • Loading branch information
webmaster128 authored Aug 20, 2024
2 parents 9a1c80c + b74215c commit d20aca7
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 12 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,15 @@ and this project adheres to
[`is_human_readable`](https://docs.rs/serde/latest/serde/trait.Serializer.html#method.is_human_readable).
This is to make these types more efficient when used together with the new
[MessagePack](https://msgpack.org) encoding. ([#2118])
- cosmwasm-std: Let `mock_env` return a contract address that is valid bech32
and uses the same bech32 prefix as `MockApi`; Change `MOCK_CONTRACT_ADDR`
value to match the contract address from `mock_env`. ([#2211])
- cosmwasm-vm: Let `mock_env` return a contract address that is valid bech32 and
uses the same bech32 prefix as `MockApi`; Change `MOCK_CONTRACT_ADDR` value to
match the contract address from `mock_env`. ([#2211])

[#2118]: https://github.com/CosmWasm/cosmwasm/pull/2118
[#2211]: https://github.com/CosmWasm/cosmwasm/issues/2211

## [2.1.3] - 2024-08-08

Expand Down
68 changes: 63 additions & 5 deletions packages/std/src/testing/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ use crate::{ChannelResponse, IbcQuery, ListChannelsResponse, PortIdResponse};
use crate::{Decimal256, DelegationRewardsResponse, DelegatorValidatorsResponse};
use crate::{RecoverPubkeyError, StdError, StdResult, SystemError, VerificationError};

pub const MOCK_CONTRACT_ADDR: &str = "cosmos2contract";
pub const MOCK_CONTRACT_ADDR: &str =
"cosmwasm1jpev2csrppg792t22rn8z8uew8h3sjcpglcd0qv9g8gj8ky922tscp8avs";

/// Creates all external requirements that can be injected for unit tests.
///
Expand Down Expand Up @@ -337,12 +338,62 @@ fn validate_length(bytes: &[u8]) -> StdResult<()> {
}
}

/// Returns a default environment with height, time, chain_id, and contract address
/// Returns a default environment with height, time, chain_id, and contract address.
/// You can submit as is to most contracts, or modify height/time if you want to
/// test for expiration.
///
/// This is intended for use in test code only.
///
/// The contract address uses the same bech32 prefix as [`MockApi`](crate::testing::MockApi). While
/// this is good for the majority of users, you might need to create your `Env`s
/// differently if you need a valid address using a different prefix.
///
/// ## Examples
///
/// Create an env:
///
/// ```
/// # use cosmwasm_std::{Addr, BlockInfo, ContractInfo, Env, Timestamp, TransactionInfo};
/// use cosmwasm_std::testing::mock_env;
///
/// let env = mock_env();
/// assert_eq!(env, Env {
/// block: BlockInfo {
/// height: 12_345,
/// time: Timestamp::from_nanos(1_571_797_419_879_305_533),
/// chain_id: "cosmos-testnet-14002".to_string(),
/// },
/// transaction: Some(TransactionInfo { index: 3 }),
/// contract: ContractInfo {
/// address: Addr::unchecked("cosmwasm1jpev2csrppg792t22rn8z8uew8h3sjcpglcd0qv9g8gj8ky922tscp8avs"),
/// },
/// });
/// ```
///
/// Mutate and reuse environment:
///
/// ```
/// # use cosmwasm_std::{Addr, BlockInfo, ContractInfo, Env, Timestamp, TransactionInfo};
/// use cosmwasm_std::testing::mock_env;
///
/// let env1 = mock_env();
///
/// // First test with `env1`
///
/// let mut env2 = env1.clone();
/// env2.block.height += 1;
/// env2.block.time = env1.block.time.plus_seconds(6);
///
/// // `env2` is one block and 6 seconds later
///
/// let mut env3 = env2.clone();
/// env3.block.height += 1;
/// env3.block.time = env2.block.time.plus_nanos(5_500_000_000);
///
/// // `env3` is one block and 5.5 seconds later
/// ```
pub fn mock_env() -> Env {
let contract_addr = MockApi::default().addr_make("cosmos2contract");
Env {
block: BlockInfo {
height: 12_345,
Expand All @@ -351,7 +402,7 @@ pub fn mock_env() -> Env {
},
transaction: Some(TransactionInfo { index: 3 }),
contract: ContractInfo {
address: Addr::unchecked(MOCK_CONTRACT_ADDR),
address: contract_addr,
},
}
}
Expand Down Expand Up @@ -688,7 +739,8 @@ pub struct BankQuerier {
#[allow(dead_code)]
/// BTreeMap<denom, amount>
supplies: BTreeMap<String, Uint128>,
/// BTreeMap<address, coins>
/// A map from address to balance. The address is the String conversion of `Addr`,
/// i.e. the bech32 encoded address.
balances: BTreeMap<String, Vec<Coin>>,
/// Vec<Metadata>
denom_metadata: BTreeMap<Vec<u8>, DenomMetadata>,
Expand All @@ -698,7 +750,7 @@ impl BankQuerier {
pub fn new(balances: &[(&str, &[Coin])]) -> Self {
let balances: BTreeMap<_, _> = balances
.iter()
.map(|(s, c)| (s.to_string(), c.to_vec()))
.map(|(address, balance)| (address.to_string(), balance.to_vec()))
.collect();

BankQuerier {
Expand Down Expand Up @@ -1204,6 +1256,12 @@ mod tests {
const ETH_BLOCK_HEADER: &[u8] =
include_bytes!("../../../crypto/testdata/eth-headers/1699693797.394876721s.json");

#[test]
fn mock_env_matches_mock_contract_addr() {
let contract_address = mock_env().contract.address;
assert_eq!(contract_address, Addr::unchecked(MOCK_CONTRACT_ADDR));
}

#[test]
fn mock_info_works() {
#[allow(deprecated)]
Expand Down
8 changes: 4 additions & 4 deletions packages/vm/src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -914,7 +914,7 @@ mod tests {

let report2 = instance.create_gas_report();
assert_eq!(report2.used_externally, 251);
assert_eq!(report2.used_internally, 16995280);
assert_eq!(report2.used_internally, 17457465);
assert_eq!(report2.limit, LIMIT);
assert_eq!(
report2.remaining,
Expand Down Expand Up @@ -1105,7 +1105,7 @@ mod tests {
.unwrap();

let init_used = orig_gas - instance.get_gas_left();
assert_eq!(init_used, 16995531);
assert_eq!(init_used, 17457716);
}

#[test]
Expand All @@ -1130,7 +1130,7 @@ mod tests {
.unwrap();

let execute_used = gas_before_execute - instance.get_gas_left();
assert_eq!(execute_used, 19589666);
assert_eq!(execute_used, 21041196);
}

#[test]
Expand Down Expand Up @@ -1173,6 +1173,6 @@ mod tests {
);

let query_used = gas_before_query - instance.get_gas_left();
assert_eq!(query_used, 11942871);
assert_eq!(query_used, 12631261);
}
}
64 changes: 61 additions & 3 deletions packages/vm/src/testing/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ use super::storage::MockStorage;
use crate::backend::unwrap_or_return_with_gas;
use crate::{Backend, BackendApi, BackendError, BackendResult, GasInfo};

pub const MOCK_CONTRACT_ADDR: &str = "cosmwasmcontract"; // TODO: use correct address
pub const MOCK_CONTRACT_ADDR: &str =
"cosmwasm1jpev2csrppg792t22rn8z8uew8h3sjcpglcd0qv9g8gj8ky922tscp8avs";

/// Default gas multiplier in wasmd.
/// See https://github.com/CosmWasm/wasmd/blob/v0.51.0/x/wasm/types/gas_register.go#L34
const WASMD_GAS_MULTIPLIER: u64 = 140_000;
Expand Down Expand Up @@ -216,12 +218,62 @@ fn validate_length(bytes: &[u8]) -> Result<(), BackendError> {
}
}

/// Returns a default environment with height, time, chain_id, and contract address
/// Returns a default environment with height, time, chain_id, and contract address.
/// You can submit as is to most contracts, or modify height/time if you want to
/// test for expiration.
///
/// This is intended for use in test code only.
///
/// The contract address uses the same bech32 prefix as [`MockApi`](crate::testing::MockApi). While
/// this is good for the majority of users, you might need to create your `Env`s
/// differently if you need a valid address using a different prefix.
///
/// ## Examples
///
/// Create an env:
///
/// ```
/// # use cosmwasm_std::{Addr, BlockInfo, ContractInfo, Env, Timestamp, TransactionInfo};
/// use cosmwasm_vm::testing::mock_env;
///
/// let env = mock_env();
/// assert_eq!(env, Env {
/// block: BlockInfo {
/// height: 12_345,
/// time: Timestamp::from_nanos(1_571_797_419_879_305_533),
/// chain_id: "cosmos-testnet-14002".to_string(),
/// },
/// transaction: Some(TransactionInfo { index: 3 }),
/// contract: ContractInfo {
/// address: Addr::unchecked("cosmwasm1jpev2csrppg792t22rn8z8uew8h3sjcpglcd0qv9g8gj8ky922tscp8avs"),
/// },
/// });
/// ```
///
/// Mutate and reuse environment:
///
/// ```
/// # use cosmwasm_std::{Addr, BlockInfo, ContractInfo, Env, Timestamp, TransactionInfo};
/// use cosmwasm_vm::testing::mock_env;
///
/// let env1 = mock_env();
///
/// // First test with `env1`
///
/// let mut env2 = env1.clone();
/// env2.block.height += 1;
/// env2.block.time = env1.block.time.plus_seconds(6);
///
/// // `env2` is one block and 6 seconds later
///
/// let mut env3 = env2.clone();
/// env3.block.height += 1;
/// env3.block.time = env2.block.time.plus_nanos(5_500_000_000);
///
/// // `env3` is one block and 5.5 seconds later
/// ```
pub fn mock_env() -> Env {
let contract_addr = MockApi::default().addr_make("cosmos2contract");
Env {
block: BlockInfo {
height: 12_345,
Expand All @@ -230,7 +282,7 @@ pub fn mock_env() -> Env {
},
transaction: Some(TransactionInfo { index: 3 }),
contract: ContractInfo {
address: Addr::unchecked(MOCK_CONTRACT_ADDR),
address: Addr::unchecked(contract_addr),
},
}
}
Expand All @@ -249,6 +301,12 @@ mod tests {
use super::*;
use cosmwasm_std::coins;

#[test]
fn mock_env_matches_mock_contract_addr() {
let contract_address = mock_env().contract.address;
assert_eq!(contract_address, Addr::unchecked(MOCK_CONTRACT_ADDR));
}

#[test]
fn mock_info_works() {
let info = mock_info("my name", &coins(100, "atom"));
Expand Down

0 comments on commit d20aca7

Please sign in to comment.