Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: cherry pick address gen #1

Open
wants to merge 24 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
492 changes: 251 additions & 241 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ schemars = "0.8.1"
serde = { version = "1.0", default-features = false, features = ["derive"] }
prost = "0.9"
anyhow = "1.0.41"
sha2 = "0.10.8"
thiserror = "1.0"
derivative = "2"

Expand All @@ -47,3 +48,4 @@ regex = "1.7.3"
# Once we bump `cosmwasm-*` deps to a version after `1.1.5`, we can remove these.
serde_json = "1.0.40"
test-case = "3.0.0"
bech32 = "0.9.1"
129 changes: 129 additions & 0 deletions src/addresses.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
//! # 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 {}
59 changes: 35 additions & 24 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use anyhow::bail;
use anyhow::Result as AnyResult;
use cosmwasm_std::testing::{mock_env, MockApi, MockStorage};
use cosmwasm_std::{
from_binary, from_slice, to_binary, Addr, AllBalanceResponse, Api, BalanceResponse, BankQuery,
from_binary, from_slice, to_json_binary, Addr, AllBalanceResponse, Api, BalanceResponse, BankQuery,
Binary, BlockInfo, ContractInfoResponse, ContractResult, CosmosMsg, CustomQuery, Empty, GovMsg,
IbcMsg, IbcQuery, Querier, QuerierResult, QuerierWrapper, QueryRequest, Record, Storage,
SupplyResponse, SystemError, SystemResult, WasmQuery,
Expand Down Expand Up @@ -74,7 +74,7 @@ pub struct App<
Stargate = StargateKeeper<Empty, Empty>,
> {
pub router: RefCell<Router<Bank, Custom, Wasm, Staking, Distr, Ibc, Gov, Stargate>>,
api: Api,
pub api: Api,
storage: RefCell<Storage>,
block: RefCell<BlockInfo>,
}
Expand Down Expand Up @@ -212,7 +212,7 @@ pub type BasicAppBuilder<ExecC, QueryC> = AppBuilder<

/// Utility to build App in stages. If particular items wont be set, defaults would be used
pub struct AppBuilder<Bank, Api, Storage, Custom, Wasm, Staking, Distr, Ibc, Gov, Stargate> {
api: Api,
pub api: Api,
block: BlockInfo,
storage: Storage,
bank: Bank,
Expand Down Expand Up @@ -844,14 +844,25 @@ where
/// This registers contract code (like uploading wasm bytecode on a chain),
/// so it can later be used to instantiate a contract.
pub fn store_code(&self, code: Box<dyn Contract<CustomT::ExecT, CustomT::QueryT>>) -> u64 {
self.init_modules(|router, _, _| router.wasm.store_code(code) as u64)
self.init_modules(|router, _, _| {
router
.wasm
.store_code(Addr::unchecked("code-creator"), code) as u64
})
}

pub fn store_code_with_creator(
&self,
creator: Addr,
code: Box<dyn Contract<CustomT::ExecT, CustomT::QueryT>>,
) -> u64 {
self.init_modules(|router, _, _| router.wasm.store_code(creator, code))
}

/// This allows to get `ContractData` for specific contract
pub fn contract_data(&self, address: &Addr) -> AnyResult<ContractData> {
self.read_module(|router, _, storage| router.wasm.load_contract(storage, address))
self.read_module(|router, _, storage| router.wasm.contract_data(storage, address))
}

/// This gets a raw state dump of all key-values held by a given contract
pub fn dump_wasm_raw(&self, address: &Addr) -> Vec<Record> {
self.read_module(|router, _, storage| router.wasm.dump_wasm_raw(storage, address))
Expand Down Expand Up @@ -937,7 +948,7 @@ where
contract_addr: U,
msg: &T,
) -> AnyResult<AppResponse> {
let msg = to_binary(msg)?;
let msg = to_json_binary(msg)?;

let Self {
block,
Expand Down Expand Up @@ -1180,7 +1191,7 @@ where
.collect::<Vec<_>>(),
pagination: None,
};
Ok(to_binary(&res)?)
Ok(to_json_binary(&res)?)
}
QUERY_BALANCE_PATH => {
let req: QueryBalanceRequest = data.try_into()?;
Expand All @@ -1200,7 +1211,7 @@ where
balance: Some(res.amount.into()),
};

Ok(to_binary(&res)?)
Ok(to_json_binary(&res)?)
}
QUERY_SUPPLY_PATH => {
let req: QuerySupplyOfRequest = data.try_into()?;
Expand All @@ -1213,7 +1224,7 @@ where
amount: Some(res.amount.into()),
};

Ok(to_binary(&res)?)
Ok(to_json_binary(&res)?)
}
// Wasm module queries
QUERY_WASM_CONTRACT_SMART_PATH => {
Expand All @@ -1227,7 +1238,7 @@ where
let res = QuerySmartContractStateResponse {
data: bin_res.into(),
};
Ok(to_binary(&res)?)
Ok(to_json_binary(&res)?)
}
QUERY_WASM_CONTRACT_INFO_PATH => {
let req: QueryContractInfoRequest = data.try_into()?;
Expand All @@ -1249,7 +1260,7 @@ where
extension: None,
}),
};
Ok(to_binary(&res)?)
Ok(to_json_binary(&res)?)
}
// The rest of all stargate queries go to the stargate module
_ => self.stargate.query(
Expand Down Expand Up @@ -1394,7 +1405,7 @@ mod test {
use super::*;
use cosmwasm_std::testing::MockQuerier;
use cosmwasm_std::{
coin, coins, to_binary, AllBalanceResponse, Attribute, BankMsg, BankQuery, Coin, Event,
coin, coins, to_json_binary, AllBalanceResponse, Attribute, BankMsg, BankQuery, Coin, Event,
OverflowError, OverflowOperation, Reply, StdError, StdResult, SubMsg, WasmMsg,
};

Expand Down Expand Up @@ -1812,7 +1823,7 @@ mod test {
let msg = payout::SudoMsg { set_count: 49 };
let sudo_msg = WasmSudo {
contract_addr: payout_addr.clone(),
msg: to_binary(&msg).unwrap(),
msg: to_json_binary(&msg).unwrap(),
};
app.sudo(sudo_msg.into()).unwrap();

Expand Down Expand Up @@ -2376,7 +2387,7 @@ mod test {
SubMsg::reply_always(
CosmosMsg::Wasm(WasmMsg::Execute {
contract_addr: contract.into(),
msg: to_binary(&echo::Message {
msg: to_json_binary(&echo::Message {
data,
sub_msg,
..echo::Message::default()
Expand All @@ -2396,7 +2407,7 @@ mod test {
let data = data.into().map(|s| s.to_owned());
SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute {
contract_addr: contract.into(),
msg: to_binary(&echo::Message {
msg: to_json_binary(&echo::Message {
data,
sub_msg,
..echo::Message::default()
Expand Down Expand Up @@ -2592,7 +2603,7 @@ mod test {
let reflect_msg = reflect::Message {
messages: vec![SubMsg::new(WasmMsg::Execute {
contract_addr: echo_addr.to_string(),
msg: to_binary(&echo_msg).unwrap(),
msg: to_json_binary(&echo_msg).unwrap(),
funds: vec![],
})],
};
Expand Down Expand Up @@ -2998,7 +3009,7 @@ mod test {

// set up reflect contract
let code_id = app.store_code(reflect::contract());
let init_msg = to_binary(&EmptyMsg {}).unwrap();
let init_msg = to_json_binary(&EmptyMsg {}).unwrap();
let msg = WasmMsg::Instantiate {
admin: None,
code_id,
Expand Down Expand Up @@ -3031,7 +3042,7 @@ mod test {
data: Some("food".into()),
sub_msg: None,
};
let init_msg = to_binary(&msg).unwrap();
let init_msg = to_json_binary(&msg).unwrap();
let msg = WasmMsg::Instantiate {
admin: None,
code_id,
Expand Down Expand Up @@ -3071,7 +3082,7 @@ mod test {
let sub_msg = SubMsg::reply_on_success(
WasmMsg::Execute {
contract_addr: addr1.to_string(),
msg: to_binary(&msg).unwrap(),
msg: to_json_binary(&msg).unwrap(),
funds: vec![],
},
EXECUTE_REPLY_BASE_ID,
Expand All @@ -3080,7 +3091,7 @@ mod test {
data: Some("Overwrite me".into()),
sub_msg: Some(vec![sub_msg]),
};
let init_msg = to_binary(&init_msg).unwrap();
let init_msg = to_json_binary(&init_msg).unwrap();
let msg = WasmMsg::Instantiate {
admin: None,
code_id,
Expand Down Expand Up @@ -3199,7 +3210,7 @@ mod test {
// execute should error
let msg = WasmMsg::Execute {
contract_addr: error_addr.into(),
msg: to_binary(&EmptyMsg {}).unwrap(),
msg: to_json_binary(&EmptyMsg {}).unwrap(),
funds: vec![],
};
let err = app
Expand Down Expand Up @@ -3242,9 +3253,9 @@ mod test {
// caller1 calls caller2, caller2 calls error
let msg = WasmMsg::Execute {
contract_addr: caller_addr2.into(),
msg: to_binary(&WasmMsg::Execute {
msg: to_json_binary(&WasmMsg::Execute {
contract_addr: error_addr.into(),
msg: to_binary(&EmptyMsg {}).unwrap(),
msg: to_json_binary(&EmptyMsg {}).unwrap(),
funds: vec![],
})
.unwrap(),
Expand Down
8 changes: 4 additions & 4 deletions src/bank.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use itertools::Itertools;
use schemars::JsonSchema;

use cosmwasm_std::{
coin, to_binary, Addr, AllBalanceResponse, Api, BalanceResponse, BankMsg, BankQuery, Binary,
coin, to_json_binary, Addr, AllBalanceResponse, Api, BalanceResponse, BankMsg, BankQuery, Binary,
BlockInfo, Coin, Event, Order, Querier, StdResult, Storage, SupplyResponse, Uint128,
};
use cw_storage_plus::Map;
Expand Down Expand Up @@ -206,7 +206,7 @@ impl Module for BankKeeper {
let address = api.addr_validate(&address)?;
let amount = self.get_balance(&bank_storage, &address)?;
let res = AllBalanceResponse { amount };
Ok(to_binary(&res)?)
Ok(to_json_binary(&res)?)
}
BankQuery::Balance { address, denom } => {
let address = api.addr_validate(&address)?;
Expand All @@ -216,13 +216,13 @@ impl Module for BankKeeper {
.find(|c| c.denom == denom)
.unwrap_or_else(|| coin(0, denom));
let res = BalanceResponse { amount };
Ok(to_binary(&res)?)
Ok(to_json_binary(&res)?)
}
BankQuery::Supply { denom } => {
let supply = self.get_supply(&bank_storage, &denom)?;
let mut res = SupplyResponse::default();
res.amount = Coin::new(supply.u128(), denom);
Ok(to_binary(&res)?)
Ok(to_json_binary(&res)?)
}
q => bail!("Unsupported bank query: {:?}", q),
}
Expand Down
Loading