clone-cw-multi-test 0.6.5

Testing tools for multi-contract interactions. Helps simulating chain behavior with on-chain storage locally
Documentation
//! # Implementation of address generators

use crate::error::AnyResult;
use crate::prefixed_storage::prefixed_read;
use crate::wasm::{CONTRACTS, NAMESPACE_WASM};
use cosmwasm_std::{Addr, Api, CanonicalAddr, HexBinary, Order, Storage};

/// Common address generator interface.
///
/// The default implementation of this trait generates fully predictable
/// addresses, no matter if [contract_address](AddressGenerator::contract_address)
/// or [predictable_contract_address](AddressGenerator::predictable_contract_address) is used,
/// but users should not make any assumptions about the value of the generated address.
pub trait AddressGenerator {
    #[deprecated(
        since = "0.18.0",
        note = "use `contract_address` or `predictable_contract_address` instead; will be removed in version 1.0.0"
    )]
    fn next_address(&self, storage: &mut dyn Storage) -> Addr {
        //TODO After removing this function in version 1.0, make `CONTRACTS` and `NAMESPACE_WASM` private in `wasm.rs`.
        let count = CONTRACTS
            .range_raw(
                &prefixed_read(storage, NAMESPACE_WASM),
                None,
                None,
                Order::Ascending,
            )
            .count();
        Addr::unchecked(format!("contract{}", count))
    }

    /// Generates a _non-predictable_ contract address, just like the real-life chain
    /// returns contract address after its instantiation.
    /// Address generated by this function is returned as a result of processing
    /// `WasmMsg::Instantiate` message.
    ///
    /// The default implementation generates a contract address based
    /// on contract's instance identifier only.
    ///
    /// # Example
    ///
    /// ```
    /// # use cosmwasm_std::testing::{MockApi, MockStorage};
    /// # use cw_multi_test::{AddressGenerator, SimpleAddressGenerator};
    /// # let api = MockApi::default();
    /// # let mut storage = MockStorage::default();
    /// struct MyAddressGenerator;
    ///
    /// impl AddressGenerator for MyAddressGenerator {}
    ///
    /// let my_address_generator = MyAddressGenerator{};
    ///
    /// let addr = my_address_generator.contract_address(&api, &mut storage, 100, 0).unwrap();
    /// assert_eq!(addr.to_string(),"contract0");
    ///
    /// let addr = my_address_generator.contract_address(&api, &mut storage, 100, 1).unwrap();
    /// assert_eq!(addr.to_string(),"contract1");
    ///
    /// let addr = my_address_generator.contract_address(&api, &mut storage, 200, 5).unwrap();
    /// assert_eq!(addr.to_string(),"contract5");
    ///
    /// let addr = my_address_generator.contract_address(&api, &mut storage, 200, 6).unwrap();
    /// assert_eq!(addr.to_string(),"contract6");
    /// ```
    fn contract_address(
        &self,
        _api: &dyn Api,
        _storage: &mut dyn Storage,
        _code_id: u64,
        instance_id: u64,
    ) -> AnyResult<Addr> {
        Ok(Addr::unchecked(format!("contract{instance_id}")))
    }

    /// Generates a _predictable_ contract address, just like the real-life chain
    /// returns contract address after its instantiation using `MsgInstantiateContract2` message.
    /// Address generated by this function is returned as a result of processing
    /// `WasmMsg::Instantiate2` message.
    ///
    /// The default implementation generates a contract address based on provided salt only.
    ///
    /// # Example
    ///
    /// ```
    /// # use cosmwasm_std::Api;
    /// # use cosmwasm_std::testing::{MockApi, MockStorage};
    /// # use cw_multi_test::{AddressGenerator, SimpleAddressGenerator};
    /// # let api = MockApi::default();
    /// # let mut storage = MockStorage::default();
    /// # let creator = api.addr_canonicalize("creator").unwrap();
    /// struct MyAddressGenerator;
    ///
    /// impl AddressGenerator for MyAddressGenerator {}
    ///
    /// let my_address_generator = MyAddressGenerator{};
    ///
    /// let addr = my_address_generator.predictable_contract_address(&api, &mut storage, 100, 0, &[0], &creator, &[0]).unwrap();
    /// assert_eq!(addr.to_string(),"contract00");
    ///
    /// let addr = my_address_generator.predictable_contract_address(&api, &mut storage, 100, 1, &[1], &creator, &[0]).unwrap();
    /// assert_eq!(addr.to_string(),"contract00");
    ///
    /// let addr = my_address_generator.predictable_contract_address(&api, &mut storage, 200, 0, &[2], &creator, &[1]).unwrap();
    /// assert_eq!(addr.to_string(),"contract01");
    ///
    /// let addr = my_address_generator.predictable_contract_address(&api, &mut storage, 200, 1, &[3], &creator, &[1]).unwrap();
    /// assert_eq!(addr.to_string(),"contract01");
    /// ```
    fn predictable_contract_address(
        &self,
        _api: &dyn Api,
        _storage: &mut dyn Storage,
        _code_id: u64,
        _instance_id: u64,
        _checksum: &[u8],
        _creator: &CanonicalAddr,
        salt: &[u8],
    ) -> AnyResult<Addr> {
        Ok(Addr::unchecked(format!(
            "contract{}",
            HexBinary::from(salt).to_hex()
        )))
    }
}

/// Default contract address generator used in [WasmKeeper](crate::WasmKeeper).
pub struct SimpleAddressGenerator;

impl AddressGenerator for SimpleAddressGenerator {}