Skip to content

Commit

Permalink
added ability to voice to specify chain address length for proxies
Browse files Browse the repository at this point in the history
  • Loading branch information
NoahSaso committed May 26, 2024
1 parent adcbc3c commit dce1fdb
Show file tree
Hide file tree
Showing 11 changed files with 124 additions and 26 deletions.
58 changes: 47 additions & 11 deletions contracts/main/voice/src/contract.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#[cfg(not(feature = "library"))]
use cosmwasm_std::entry_point;
use cosmwasm_std::{
from_json, instantiate2_address, to_json_binary, to_json_vec, Binary, CodeInfoResponse,
ContractResult, Deps, DepsMut, Env, MessageInfo, Response, StdResult, SubMsg, SystemResult,
Uint64, WasmMsg,
from_json, instantiate2_address, to_json_binary, to_json_vec, Binary, CanonicalAddr,
CodeInfoResponse, ContractResult, Deps, DepsMut, Env, MessageInfo, Response, StdResult, SubMsg,
SystemResult, Uint64, WasmMsg,
};
use cw2::set_contract_version;

Expand All @@ -13,7 +13,9 @@ use polytone::ibc::{Msg, Packet};
use crate::error::ContractError;
use crate::ibc::{ACK_GAS_NEEDED, REPLY_FORWARD_DATA};
use crate::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg};
use crate::state::{BLOCK_MAX_GAS, PROXY_CODE_ID, SENDER_TO_PROXY};
use crate::state::{
SenderInfo, BLOCK_MAX_GAS, CONTRACT_ADDR_LEN, PROXY_CODE_ID, PROXY_TO_SENDER, SENDER_TO_PROXY,
};

const CONTRACT_NAME: &str = "crates.io:polytone-voice";
const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION");
Expand All @@ -35,13 +37,20 @@ pub fn instantiate(
return Err(ContractError::GasLimitsMismatch);
}

let contract_addr_len = msg.contract_addr_len.unwrap_or(32);
if contract_addr_len == 0 {
return Err(ContractError::ContractAddrLenCantBeZero);
}

PROXY_CODE_ID.save(deps.storage, &msg.proxy_code_id.u64())?;
BLOCK_MAX_GAS.save(deps.storage, &msg.block_max_gas.u64())?;
CONTRACT_ADDR_LEN.save(deps.storage, &contract_addr_len)?;

Ok(Response::default()
.add_attribute("method", "instantiate")
.add_attribute("proxy_code_id", msg.proxy_code_id)
.add_attribute("block_max_gas", msg.block_max_gas))
.add_attribute("block_max_gas", msg.block_max_gas)
.add_attribute("contract_addr_len", contract_addr_len.to_string()))
}

#[cfg_attr(not(feature = "library"), entry_point)]
Expand Down Expand Up @@ -104,17 +113,33 @@ pub fn execute(
let contract =
deps.api.addr_canonicalize(env.contract.address.as_str())?;
let code_id = PROXY_CODE_ID.load(deps.storage)?;
let addr_len = CONTRACT_ADDR_LEN.load(deps.storage)?;
let CodeInfoResponse { checksum, .. } =
deps.querier.query_wasm_code_info(code_id)?;
let salt = salt(&connection_id, &counterparty_port, &sender);
let proxy = deps.api.addr_humanize(&instantiate2_address(
&checksum, &contract, &salt,
)?)?;
let init2_addr_data: CanonicalAddr =
instantiate2_address(&checksum, &contract, &salt)?.to_vec()
[0..addr_len as usize]
.into();
let proxy = deps.api.addr_humanize(&init2_addr_data)?;
SENDER_TO_PROXY.save(
deps.storage,
(connection_id, counterparty_port, sender.clone()),
(
connection_id.clone(),
counterparty_port.clone(),
sender.clone(),
),
&proxy,
)?;
PROXY_TO_SENDER.save(
deps.storage,
proxy.clone(),
&SenderInfo {
connection_id,
remote_port: counterparty_port,
remote_sender: sender.clone(),
},
)?;
(
Some(WasmMsg::Instantiate2 {
admin: None,
Expand Down Expand Up @@ -171,6 +196,10 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult<Binary> {
match msg {
QueryMsg::BlockMaxGas => to_json_binary(&BLOCK_MAX_GAS.load(deps.storage)?),
QueryMsg::ProxyCodeId => to_json_binary(&PROXY_CODE_ID.load(deps.storage)?),
QueryMsg::ContractAddrLen => to_json_binary(&CONTRACT_ADDR_LEN.load(deps.storage)?),
QueryMsg::SenderInfoForProxy { proxy } => {
to_json_binary(&PROXY_TO_SENDER.load(deps.storage, deps.api.addr_validate(&proxy)?)?)
}
}
}

Expand All @@ -180,6 +209,7 @@ pub fn migrate(deps: DepsMut, _env: Env, msg: MigrateMsg) -> Result<Response, Co
MigrateMsg::WithUpdate {
proxy_code_id,
block_max_gas,
contract_addr_len,
} => {
if proxy_code_id.is_zero() {
return Err(ContractError::CodeIdCantBeZero);
Expand All @@ -189,14 +219,20 @@ pub fn migrate(deps: DepsMut, _env: Env, msg: MigrateMsg) -> Result<Response, Co
return Err(ContractError::GasLimitsMismatch);
}

// update the proxy code ID and block max gas
if contract_addr_len == 0 {
return Err(ContractError::ContractAddrLenCantBeZero);
}

// update the proxy code ID, block max gas, and contract addr len
PROXY_CODE_ID.save(deps.storage, &proxy_code_id.u64())?;
BLOCK_MAX_GAS.save(deps.storage, &block_max_gas.u64())?;
CONTRACT_ADDR_LEN.save(deps.storage, &contract_addr_len)?;

Ok(Response::default()
.add_attribute("method", "migrate_with_update")
.add_attribute("proxy_code_id", proxy_code_id)
.add_attribute("block_max_gas", block_max_gas))
.add_attribute("block_max_gas", block_max_gas)
.add_attribute("contract_addr_len", contract_addr_len.to_string()))
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions contracts/main/voice/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,7 @@ pub enum ContractError {

#[error("ACK_GAS_NEEDED can't be higher then BLOCK_MAX_GAS")]
GasLimitsMismatch,

#[error("Contract address length can't be zero")]
ContractAddrLenCantBeZero,
}
13 changes: 13 additions & 0 deletions contracts/main/voice/src/msg.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
use cosmwasm_schema::{cw_serde, QueryResponses};
use cosmwasm_std::{Binary, Uint64};

use crate::state::SenderInfo;

#[cw_serde]
pub struct InstantiateMsg {
/// Code ID to use for instantiating proxy contracts.
pub proxy_code_id: Uint64,
/// The max gas allowed in a single block.
pub block_max_gas: Uint64,
/// The contract address length used by the chain. Defaults to 32. Some
/// chains use other lengths, such as Injective which uses 20.
pub contract_addr_len: Option<u8>,
}

#[cw_serde]
Expand Down Expand Up @@ -35,6 +40,12 @@ pub enum QueryMsg {
/// `"proxy_code_id"`.
#[returns(Uint64)]
ProxyCodeId,
/// Queries the configured contract address length.
#[returns(u8)]
ContractAddrLen,
/// Queries the sender information for a given proxy.
#[returns(SenderInfo)]
SenderInfoForProxy { proxy: String },
}

#[cw_serde]
Expand All @@ -45,5 +56,7 @@ pub enum MigrateMsg {
proxy_code_id: Uint64,
/// The max gas allowed in a single block.
block_max_gas: Uint64,
/// The contract address length used by the chain.
contract_addr_len: u8,
},
}
14 changes: 14 additions & 0 deletions contracts/main/voice/src/state.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
use cosmwasm_schema::cw_serde;
use cosmwasm_std::Addr;
use cw_storage_plus::{Item, Map};

/// (connection_id, remote_port, remote_sender) -> proxy
pub(crate) const SENDER_TO_PROXY: Map<(String, String, String), Addr> = Map::new("c2p");

/// proxy -> { connection_id, remote_port, remote_sender }
pub(crate) const PROXY_TO_SENDER: Map<Addr, SenderInfo> = Map::new("p2c");

/// (channel_id) -> connection_id
pub(crate) const CHANNEL_TO_CONNECTION: Map<String, String> = Map::new("c2c");

Expand All @@ -12,3 +16,13 @@ pub(crate) const PROXY_CODE_ID: Item<u64> = Item::new("pci");

/// Max gas usable in a single block.
pub(crate) const BLOCK_MAX_GAS: Item<u64> = Item::new("bmg");

/// Contract address length used by the chain.
pub(crate) const CONTRACT_ADDR_LEN: Item<u8> = Item::new("cal");

#[cw_serde]
pub struct SenderInfo {
pub connection_id: String,
pub remote_port: String,
pub remote_sender: String,
}
17 changes: 16 additions & 1 deletion contracts/main/voice/src/suite_tests/suite.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use cosmwasm_std::{Addr, Empty, Uint64};
use cw_multi_test::{App, AppResponse, Contract, ContractWrapper, Executor};

use crate::msg::QueryMsg::{BlockMaxGas, ProxyCodeId};
use crate::msg::QueryMsg::{BlockMaxGas, ContractAddrLen, ProxyCodeId};
use crate::msg::{InstantiateMsg, MigrateMsg};

pub const CREATOR_ADDR: &str = "creator";
Expand Down Expand Up @@ -33,6 +33,7 @@ impl Default for SuiteBuilder {
instantiate: InstantiateMsg {
proxy_code_id: Uint64::new(9999),
block_max_gas: Uint64::new(110_000),
contract_addr_len: None,
},
}
}
Expand Down Expand Up @@ -95,6 +96,13 @@ impl Suite {
.query_wasm_smart(&self.voice_address, &ProxyCodeId)
.unwrap()
}

pub fn query_contract_addr_len(&self) -> u8 {
self.app
.wrap()
.query_wasm_smart(&self.voice_address, &ContractAddrLen)
.unwrap()
}
}

// migrate
Expand All @@ -104,13 +112,15 @@ impl Suite {
sender: Addr,
contract_code_id: u64,
block_max_gas: u64,
contract_addr_len: u8,
) -> anyhow::Result<AppResponse> {
self.app.migrate_contract(
sender,
self.voice_address.clone(),
&MigrateMsg::WithUpdate {
proxy_code_id: contract_code_id.into(),
block_max_gas: block_max_gas.into(),
contract_addr_len: contract_addr_len,
},
self.voice_code,
)
Expand All @@ -128,4 +138,9 @@ impl Suite {
let curr = self.query_proxy_code_id();
assert_eq!(curr, val);
}

pub fn assert_contract_addr_len(&self, val: u8) {
let curr = self.query_contract_addr_len();
assert_eq!(curr, val);
}
}
23 changes: 18 additions & 5 deletions contracts/main/voice/src/suite_tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ fn test_update() {
let proxy_code_new = suite.store_voice_contract();

suite
.update(Addr::unchecked(CREATOR_ADDR), proxy_code_new, 111_000)
.update(Addr::unchecked(CREATOR_ADDR), proxy_code_new, 111_000, 32)
.unwrap();

// assert that both fields updated succesfully
Expand All @@ -31,7 +31,7 @@ fn test_query_block_max_gas() {
suite.assert_block_max_gas(110_000);

suite
.update(Addr::unchecked(CREATOR_ADDR), suite.voice_code, 111_000)
.update(Addr::unchecked(CREATOR_ADDR), suite.voice_code, 111_000, 32)
.unwrap();

suite.assert_block_max_gas(111_000);
Expand All @@ -44,12 +44,25 @@ fn test_query_proxy_code_id() {
suite.assert_proxy_code(9999);

suite
.update(Addr::unchecked(CREATOR_ADDR), 1, 110_000)
.update(Addr::unchecked(CREATOR_ADDR), 1, 110_000, 32)
.unwrap();

suite.assert_proxy_code(1);
}

#[test]
fn test_query_contract_addr_len() {
let mut suite = SuiteBuilder::default().build();

suite.assert_contract_addr_len(32);

suite
.update(Addr::unchecked(CREATOR_ADDR), 1, 110_000, 20)
.unwrap();

suite.assert_contract_addr_len(20);
}

#[test]
#[should_panic]
fn test_code_id_validation() {
Expand All @@ -71,15 +84,15 @@ fn test_migrate_validation() {
let mut suite = SuiteBuilder::default().build();

let err = suite
.update(Addr::unchecked(CREATOR_ADDR), 0, 110_000)
.update(Addr::unchecked(CREATOR_ADDR), 0, 110_000, 32)
.unwrap_err()
.downcast::<ContractError>()
.unwrap();

assert_eq!(err, ContractError::CodeIdCantBeZero);

let err = suite
.update(Addr::unchecked(CREATOR_ADDR), 1, 0)
.update(Addr::unchecked(CREATOR_ADDR), 1, 0, 32)
.unwrap_err()
.downcast::<ContractError>()
.unwrap();
Expand Down
1 change: 1 addition & 0 deletions packages/cw-orch-polytone/src/deploy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ impl<Chain: CwEnv> Deploy<Chain> for Polytone<Chain> {
&polytone_voice::msg::InstantiateMsg {
proxy_code_id: deployment.proxy.code_id()?.into(),
block_max_gas: MAX_BLOCK_GAS.into(),
contract_addr_len: None,
},
None,
None,
Expand Down
5 changes: 3 additions & 2 deletions tests/simtests/contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ type NoteInstantiate struct {
}

type VoiceInstantiate struct {
ProxyCodeId uint64 `json:"proxy_code_id,string"`
BlockMaxGas uint64 `json:"block_max_gas,string"`
ProxyCodeId uint64 `json:"proxy_code_id,string"`
BlockMaxGas uint64 `json:"block_max_gas,string"`
ContractAddrLen uint8 `json:"contract_addr_len,string"`
}

type TesterInstantiate struct {
Expand Down
5 changes: 3 additions & 2 deletions tests/simtests/functionality_suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,9 @@ func SetupChain(t *testing.T, c *ibctesting.Coordinator, index int) Chain {
BlockMaxGas: uint64(blockMaxGas),
})
voice := Instantiate(t, chain, 2, VoiceInstantiate{
ProxyCodeId: 3,
BlockMaxGas: uint64(blockMaxGas),
ProxyCodeId: 3,
BlockMaxGas: uint64(blockMaxGas),
ContractAddrLen: 32,
})
tester := Instantiate(t, chain, 4, TesterInstantiate{})

Expand Down
6 changes: 3 additions & 3 deletions tests/strangelove/suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,11 +190,11 @@ func (s *Suite) SetupChain(chain *SuiteChain) {

chain.Note = s.Instantiate(cc, user, noteId, NoteInstantiate{})
chain.Voice = s.Instantiate(cc, user, voiceId, VoiceInstantiate{
ProxyCodeId: uint64(proxyUint),
BlockMaxGas: 100_000_000,
ProxyCodeId: uint64(proxyUint),
BlockMaxGas: 100_000_000,
ContractAddrLen: 32,
})
chain.Tester = s.Instantiate(cc, user, testerId, TesterInstantiate{})
return
}

func (s *Suite) Instantiate(chain *cosmos.CosmosChain, user *ibc.Wallet, codeId string, msg any) string {
Expand Down
5 changes: 3 additions & 2 deletions tests/strangelove/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ type NoteInstantiate struct {
}

type VoiceInstantiate struct {
ProxyCodeId uint64 `json:"proxy_code_id,string"`
BlockMaxGas uint64 `json:"block_max_gas,string"`
ProxyCodeId uint64 `json:"proxy_code_id,string"`
BlockMaxGas uint64 `json:"block_max_gas,string"`
ContractAddrLen uint8 `json:"contract_addr_len,string"`
}

type TesterInstantiate struct {
Expand Down

0 comments on commit dce1fdb

Please sign in to comment.