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

Added upload_with_access #485

5 changes: 3 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

## Unpublished

- Add methods to set the private key and mnemonic of an existing sender
- Deprecate `authz_granter` and `fee_granter` on `Daemon` struct
- Add methods to set the private key and mnemonic of an existing sender
- Deprecate `authz_granter` and `fee_granter` on `Daemon` struct
- Add a method on `TxHandler` to select instantiation permissions on Wasm upload

### Breaking

Expand Down
42 changes: 40 additions & 2 deletions cw-orch-daemon/src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ use cosmrs::{
use cosmwasm_std::{Addr, Binary, Coin};
use cw_orch_core::{
contract::interface_traits::Uploadable,
environment::{AsyncWasmQuerier, ChainInfoOwned, ChainState, IndexResponse, Querier},
environment::{
AccessConfig, AsyncWasmQuerier, ChainInfoOwned, ChainState, IndexResponse, Querier,
},
log::transaction_target,
};
use flate2::{write, Compression};
Expand Down Expand Up @@ -342,8 +344,17 @@ impl<Sender: TxSender> DaemonAsyncBase<Sender> {

/// Upload a contract to the chain.
pub async fn upload<T: Uploadable>(
&self,
uploadable: &T,
) -> Result<CosmTxResponse, DaemonError> {
self.upload_with_access_config(uploadable, None).await
}

/// Upload a contract to the chain and specify the permissions for instantiating
pub async fn upload_with_access_config<T: Uploadable>(
&self,
_uploadable: &T,
access: Option<AccessConfig>,
) -> Result<CosmTxResponse, DaemonError> {
let wasm_path = <T as Uploadable>::wasm(self.chain_info());

Expand All @@ -356,7 +367,7 @@ impl<Sender: TxSender> DaemonAsyncBase<Sender> {
let store_msg = cosmrs::cosmwasm::MsgStoreCode {
sender: self.sender().account_id(),
wasm_byte_code,
instantiate_permission: None,
instantiate_permission: access.map(access_config_to_cosmrs).transpose()?,
};

let result = self
Expand All @@ -378,6 +389,33 @@ impl<Sender: TxSender> DaemonAsyncBase<Sender> {
}
}

fn access_config_to_cosmrs(
access_config: AccessConfig,
) -> Result<cosmrs::cosmwasm::AccessConfig, DaemonError> {
let response = match access_config {
AccessConfig::Nobody => cosmrs::cosmwasm::AccessConfig {
permission: cosmrs::cosmwasm::AccessType::Nobody,
addresses: vec![],
},
AccessConfig::Everybody => cosmrs::cosmwasm::AccessConfig {
permission: cosmrs::cosmwasm::AccessType::Everybody,
addresses: vec![],
},
AccessConfig::AnyOfAddresses(addresses) => cosmrs::cosmwasm::AccessConfig {
permission: cosmrs::cosmwasm::AccessType::AnyOfAddresses,
addresses: addresses
.into_iter()
.map(|a| a.parse())
.collect::<Result<_, _>>()?,
},
AccessConfig::Unspecified => cosmrs::cosmwasm::AccessConfig {
permission: cosmrs::cosmwasm::AccessType::Unspecified,
addresses: vec![],
},
};
Ok(response)
}

impl Querier for DaemonAsync {
type Error = DaemonError;
}
Expand Down
2 changes: 1 addition & 1 deletion cw-orch-daemon/src/senders/query_only.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ impl QuerySender for QueryOnlySender {

#[cfg(test)]
mod tests {
use cw_orch_networks::networks::{ARCHWAY_1, JUNO_1, VOTA_ASH};
use cw_orch_networks::networks::{ARCHWAY_1, JUNO_1};

use super::QueryOnlyDaemon;
use crate::DaemonBuilder;
Expand Down
11 changes: 11 additions & 0 deletions cw-orch-daemon/src/sync/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,17 @@ impl<Sender: TxSender> TxHandler for DaemonBase<Sender> {
.instantiate2(code_id, init_msg, label, admin, coins, salt),
)
}

fn upload_with_access_config<T: Uploadable>(
&self,
contract_source: &T,
access_config: Option<cw_orch_core::environment::AccessConfig>,
) -> Result<Self::Response, Self::Error> {
self.rt_handle.block_on(
self.daemon
.upload_with_access_config(contract_source, access_config),
)
}
}

impl<Sender: TxSender> Stargate for DaemonBase<Sender> {
Expand Down
25 changes: 17 additions & 8 deletions packages/clone-testing/src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,19 @@ use clone_cw_multi_test::{
wasm_emulation::{channel::RemoteChannel, storage::analyzer::StorageAnalyzer},
App, AppBuilder, BankKeeper, Contract, Executor, WasmKeeper,
};
use cosmwasm_std::{to_json_binary, WasmMsg};
use cosmwasm_std::{Addr, Binary, Coin, CosmosMsg, Empty, Event, StdError, StdResult, Uint128};
use cw_orch_core::contract::interface_traits::ContractInstance;
use cosmwasm_std::{
to_json_binary, Addr, Binary, Coin, CosmosMsg, Empty, Event, StdError, StdResult, Uint128,
WasmMsg,
};
use cw_orch_core::{
contract::interface_traits::Uploadable,
contract::interface_traits::{ContractInstance, Uploadable},
environment::{
BankQuerier, BankSetter, ChainInfoOwned, ChainState, DefaultQueriers, IndexResponse,
StateInterface, TxHandler,
AccessConfig, BankQuerier, BankSetter, ChainInfoOwned, ChainState, DefaultQueriers,
IndexResponse, StateInterface, TxHandler,
},
CwEnvError,
};
use cw_orch_daemon::{queriers::Node, RUNTIME};
use cw_orch_daemon::{read_network_config, DEFAULT_DEPLOYMENT};
use cw_orch_daemon::{queriers::Node, read_network_config, DEFAULT_DEPLOYMENT, RUNTIME};
use cw_utils::NativeBalance;
use serde::Serialize;
use tokio::runtime::Runtime;
Expand Down Expand Up @@ -305,6 +305,15 @@ impl<S: StateInterface> TxHandler for CloneTesting<S> {
Ok(resp)
}

fn upload_with_access_config<T: Uploadable>(
&self,
contract_source: &T,
_access_config: Option<AccessConfig>,
) -> Result<Self::Response, Self::Error> {
log::debug!("Uploading with access is not enforced when using Clone Testing");
self.upload(contract_source)
}

fn execute<E: Serialize + Debug>(
&self,
exec_msg: &E,
Expand Down
19 changes: 16 additions & 3 deletions packages/cw-orch-core/src/contract/contract_instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::{
log::{contract_target, transaction_target},
};

use crate::environment::AccessConfig;
use crate::environment::QueryHandler;
use cosmwasm_std::{Addr, Binary, Coin};
use serde::{de::DeserializeOwned, Serialize};
Expand Down Expand Up @@ -102,15 +103,22 @@ impl<Chain: ChainState> Contract<Chain> {
impl<Chain: TxHandler> Contract<Chain> {
// Chain interfaces

/// Upload a contract given its source
pub fn upload(&self, source: &impl Uploadable) -> Result<TxResponse<Chain>, CwEnvError> {
/// Upload a contract given its source and specify the permissions for instantiating
pub fn upload_with_access_config(
&self,
source: &impl Uploadable,
access_config: Option<AccessConfig>,
) -> Result<TxResponse<Chain>, CwEnvError> {
log::info!(
target: &contract_target(),
"[{}][Upload]",
self.id,
);

let resp = self.chain.upload(source).map_err(Into::into)?;
let resp = self
.chain
.upload_with_access_config(source, access_config)
.map_err(Into::into)?;
let code_id = resp.uploaded_code_id()?;
self.set_code_id(code_id);
log::info!(
Expand All @@ -128,6 +136,11 @@ impl<Chain: TxHandler> Contract<Chain> {
Ok(resp)
}

/// Upload a contract given its source
pub fn upload(&self, source: &impl Uploadable) -> Result<TxResponse<Chain>, CwEnvError> {
self.upload_with_access_config(source, None)
}

/// Executes an operation on the contract
pub fn execute<E: Serialize + Debug>(
&self,
Expand Down
10 changes: 10 additions & 0 deletions packages/cw-orch-core/src/contract/interface_traits.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use super::{Contract, WasmPath};
use crate::environment::AccessConfig;
use crate::{
environment::{
AsyncWasmQuerier, ChainInfoOwned, ChainState, CwEnv, Environment, QueryHandler, TxHandler,
Expand Down Expand Up @@ -262,6 +263,15 @@ pub trait CwOrchUpload<Chain: TxHandler>: ContractInstance<Chain> + Uploadable +
fn upload(&self) -> Result<Chain::Response, CwEnvError> {
self.as_instance().upload(self)
}

/// upload the contract to the configured environment and specify the permissions for instantiating
fn upload_with_access_config(
&self,
access_config: Option<AccessConfig>,
) -> Result<Chain::Response, CwEnvError> {
self.as_instance()
.upload_with_access_config(self, access_config)
}
}

/// enable `.upload()` for contracts that implement `Uploadable` for that environment.
Expand Down
2 changes: 1 addition & 1 deletion packages/cw-orch-core/src/environment/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@ pub use queriers::{
DefaultQueriers, Querier, QuerierGetter, QueryHandler,
};
pub use state::{ChainState, StateInterface};
pub use tx_handler::{TxHandler, TxResponse};
pub use tx_handler::{AccessConfig, TxHandler, TxResponse};
Kayanski marked this conversation as resolved.
Show resolved Hide resolved
48 changes: 48 additions & 0 deletions packages/cw-orch-core/src/environment/tx_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@ pub trait TxHandler: ChainState + Clone {
/// Uploads a contract to the chain.
fn upload<T: Uploadable>(&self, contract_source: &T) -> Result<Self::Response, Self::Error>;

/// Uploads a contract to the chain and specify the permissions for instantiating
fn upload_with_access_config<T: Uploadable>(
&self,
contract_source: &T,
access_config: Option<AccessConfig>,
) -> Result<Self::Response, Self::Error>;

/// Send a InstantiateMsg to a contract.
fn instantiate<I: Serialize + Debug>(
&self,
Expand Down Expand Up @@ -81,6 +88,39 @@ pub trait TxHandler: ChainState + Clone {
}
}

pub enum AccessConfig {
Unspecified,
Nobody,
Everybody,
AnyOfAddresses(Vec<String>),
}

impl From<AccessConfig> for cosmos_sdk_proto::cosmwasm::wasm::v1::AccessConfig {
fn from(val: AccessConfig) -> Self {
match val {
AccessConfig::Nobody => cosmos_sdk_proto::cosmwasm::wasm::v1::AccessConfig {
permission: cosmos_sdk_proto::cosmwasm::wasm::v1::AccessType::Nobody.into(),
addresses: vec![],
},
AccessConfig::Everybody => cosmos_sdk_proto::cosmwasm::wasm::v1::AccessConfig {
permission: cosmos_sdk_proto::cosmwasm::wasm::v1::AccessType::Everybody.into(),
addresses: vec![],
},
AccessConfig::AnyOfAddresses(addresses) => {
cosmos_sdk_proto::cosmwasm::wasm::v1::AccessConfig {
permission: cosmos_sdk_proto::cosmwasm::wasm::v1::AccessType::AnyOfAddresses
.into(),
addresses,
}
}
AccessConfig::Unspecified => cosmos_sdk_proto::cosmwasm::wasm::v1::AccessConfig {
permission: cosmos_sdk_proto::cosmwasm::wasm::v1::AccessType::Unspecified.into(),
addresses: vec![],
},
}
}
}

// TODO: Perfect test candidate for `trybuild`
#[cfg(test)]
mod tests {
Expand Down Expand Up @@ -203,6 +243,14 @@ mod tests {
) -> Result<Self::Response, Self::Error> {
unimplemented!()
}

fn upload_with_access_config<T: Uploadable>(
&self,
_contract_source: &T,
_access_config: Option<AccessConfig>,
) -> Result<Self::Response, Self::Error> {
unimplemented!()
}
}

fn associated_error<T: TxHandler>(t: T) -> anyhow::Result<()> {
Expand Down
11 changes: 10 additions & 1 deletion packages/cw-orch-mock/src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use serde::Serialize;
use super::state::MockState;
use cw_orch_core::{
contract::interface_traits::Uploadable,
environment::{ChainState, IndexResponse, StateInterface, TxHandler},
environment::{AccessConfig, ChainState, IndexResponse, StateInterface, TxHandler},
CwEnvError,
};

Expand Down Expand Up @@ -248,6 +248,15 @@ impl<A: Api, S: StateInterface> TxHandler for MockBase<A, S> {
)
.map_err(From::from)
}

fn upload_with_access_config<T: Uploadable>(
&self,
contract_source: &T,
_access_config: Option<AccessConfig>,
) -> Result<Self::Response, Self::Error> {
log::debug!("Uploading with access is not enforced when using Mock testing");
self.upload(contract_source)
}
}

#[cfg(test)]
Expand Down
Loading