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

Rename CanSend to CanExecute for generality #146

Merged
merged 3 commits into from
Nov 30, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions contracts/cw1-subkeys/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "cw1-subkeys"
version = "0.3.2"
version = "0.4.0"
maurolacy marked this conversation as resolved.
Show resolved Hide resolved
authors = ["Ethan Frey <ethanfrey@users.noreply.github.com>"]
edition = "2018"
description = "Implement subkeys for authorizing native tokens as a cw1 proxy contract"
Expand All @@ -19,9 +19,9 @@ library = []

[dependencies]
cw0 = { path = "../../packages/cw0", version = "0.3.2" }
cw1 = { path = "../../packages/cw1", version = "0.3.2" }
cw1 = { path = "../../packages/cw1", version = "0.4.0" }
cw2 = { path = "../../packages/cw2", version = "0.3.2" }
cw1-whitelist = { path = "../cw1-whitelist", version = "0.3.2", features = ["library"] }
cw1-whitelist = { path = "../cw1-whitelist", version = "0.4.0", features = ["library"] }
cosmwasm-std = { version = "0.12.0-alpha2", features = ["iterator", "staking"] }
cosmwasm-storage = { version = "0.12.0-alpha2", features = ["iterator"] }
schemars = "0.7"
Expand Down
12 changes: 6 additions & 6 deletions contracts/cw1-subkeys/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,8 @@ const useOptions = (options: Options): Network => {

type Expiration = { at_height: { height: number } } | { at_time: { time: number } } | { never: {}}

interface CanSendResponse {
readonly canSend: boolean;
interface CanExecuteResponse {
readonly canExecute: boolean;
}

interface Permissions {
Expand Down Expand Up @@ -233,7 +233,7 @@ interface CW1Instance {

permissions: (address?: string) => Promise<PermissionsInfo>
allPermissions: (startAfter?: string, limit?: number) => Promise<AllPermissionsResponse>
canSend: (sender: string, msg: CosmosMsg) => Promise<CanSendResponse>
canExecute: (sender: string, msg: CosmosMsg) => Promise<CanExecuteResponse>

// actions
execute: (msgs: readonly CosmosMsg[]) => Promise<string>
Expand Down Expand Up @@ -278,8 +278,8 @@ const CW1 = (client: SigningCosmWasmClient): CW1Contract => {
return client.queryContractSmart(contractAddress, {all_permissions: { start_after: startAfter, limit: limit }});
};

const canSend = async (sender: string, msg: CosmosMsg): Promise<CanSendResponse> => {
return client.queryContractSmart(contractAddress, {can_send: { sender: sender, msg: msg }});
const canExecute = async (sender: string, msg: CosmosMsg): Promise<CanExecuteResponse> => {
return client.queryContractSmart(contractAddress, {can_execute: { sender: sender, msg: msg }});
};

const admins = async (): Promise<AdminListResponse> => {
Expand Down Expand Up @@ -326,7 +326,7 @@ const CW1 = (client: SigningCosmWasmClient): CW1Contract => {
allAllowances,
permissions,
allPermissions,
canSend,
canExecute,
execute,
freeze,
updateAdmins,
Expand Down
6 changes: 3 additions & 3 deletions contracts/cw1-subkeys/schema/query_msg.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,13 @@
}
},
{
"description": "Checks permissions of the caller on this proxy. If CanSend returns true then a call to `Execute` with the same message, before any further state changes, should also succeed.",
"description": "Checks permissions of the caller on this proxy. If CanExecute returns true then a call to `Execute` with the same message, before any further state changes, should also succeed.",
"type": "object",
"required": [
"can_send"
"can_execute"
],
"properties": {
"can_send": {
"can_execute": {
"type": "object",
"required": [
"msg",
Expand Down
69 changes: 37 additions & 32 deletions contracts/cw1-subkeys/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use cosmwasm_std::{
HandleResponse, HumanAddr, InitResponse, MessageInfo, Order, StakingMsg, StdError, StdResult,
};
use cw0::{calc_range_start_human, Expiration};
use cw1::CanSendResponse;
use cw1::CanExecuteResponse;
use cw1_whitelist::{
contract::{handle_freeze, handle_update_admins, init as whitelist_init, query_admin_list},
msg::InitMsg,
Expand Down Expand Up @@ -296,7 +296,7 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult<Binary> {
QueryMsg::AdminList {} => to_binary(&query_admin_list(deps)?),
QueryMsg::Allowance { spender } => to_binary(&query_allowance(deps, spender)?),
QueryMsg::Permissions { spender } => to_binary(&query_permissions(deps, spender)?),
QueryMsg::CanSend { sender, msg } => to_binary(&query_can_send(deps, sender, msg)?),
QueryMsg::CanExecute { sender, msg } => to_binary(&query_can_execute(deps, sender, msg)?),
QueryMsg::AllAllowances { start_after, limit } => {
to_binary(&query_all_allowances(deps, start_after, limit)?)
}
Expand Down Expand Up @@ -324,14 +324,18 @@ pub fn query_permissions(deps: Deps, spender: HumanAddr) -> StdResult<Permission
Ok(permissions)
}

fn query_can_send(deps: Deps, sender: HumanAddr, msg: CosmosMsg) -> StdResult<CanSendResponse> {
Ok(CanSendResponse {
can_send: can_send(deps, sender, msg)?,
fn query_can_execute(
deps: Deps,
sender: HumanAddr,
msg: CosmosMsg,
) -> StdResult<CanExecuteResponse> {
Ok(CanExecuteResponse {
can_execute: can_execute(deps, sender, msg)?,
})
}

// this can just return booleans and the query_can_send wrapper creates the struct once, not on every path
fn can_send(deps: Deps, sender: HumanAddr, msg: CosmosMsg) -> StdResult<bool> {
// this can just return booleans and the query_can_execute wrapper creates the struct once, not on every path
fn can_execute(deps: Deps, sender: HumanAddr, msg: CosmosMsg) -> StdResult<bool> {
let owner_raw = deps.api.canonical_address(&sender)?;
let cfg = admin_list_read(deps.storage).load()?;
if cfg.is_admin(&owner_raw) {
Expand Down Expand Up @@ -1445,7 +1449,7 @@ mod tests {
}

#[test]
fn can_send_query_works() {
fn can_execute_query_works() {
let mut deps = mock_dependencies(&[]);

let owner = HumanAddr::from("admin007");
Expand Down Expand Up @@ -1494,39 +1498,40 @@ mod tests {
});

// owner can send big or small
let res = query_can_send(deps.as_ref(), owner.clone(), send_msg.clone()).unwrap();
assert_eq!(res.can_send, true);
let res = query_can_send(deps.as_ref(), owner.clone(), send_msg_large.clone()).unwrap();
assert_eq!(res.can_send, true);
let res = query_can_execute(deps.as_ref(), owner.clone(), send_msg.clone()).unwrap();
assert_eq!(res.can_execute, true);
let res = query_can_execute(deps.as_ref(), owner.clone(), send_msg_large.clone()).unwrap();
assert_eq!(res.can_execute, true);
// owner can stake
let res =
query_can_send(deps.as_ref(), owner.clone(), staking_delegate_msg.clone()).unwrap();
assert_eq!(res.can_send, true);
query_can_execute(deps.as_ref(), owner.clone(), staking_delegate_msg.clone()).unwrap();
assert_eq!(res.can_execute, true);

// spender can send small
let res = query_can_send(deps.as_ref(), spender.clone(), send_msg.clone()).unwrap();
assert_eq!(res.can_send, true);
let res = query_can_execute(deps.as_ref(), spender.clone(), send_msg.clone()).unwrap();
assert_eq!(res.can_execute, true);
// not too big
let res = query_can_send(deps.as_ref(), spender.clone(), send_msg_large.clone()).unwrap();
assert_eq!(res.can_send, false);
// spender can send staking msgs if permissioned
let res =
query_can_send(deps.as_ref(), spender.clone(), staking_delegate_msg.clone()).unwrap();
assert_eq!(res.can_send, true);
let res =
query_can_send(deps.as_ref(), spender.clone(), staking_withdraw_msg.clone()).unwrap();
assert_eq!(res.can_send, false);
query_can_execute(deps.as_ref(), spender.clone(), send_msg_large.clone()).unwrap();
assert_eq!(res.can_execute, false);
// spender can send staking msgs if permissioned
let res = query_can_execute(deps.as_ref(), spender.clone(), staking_delegate_msg.clone())
.unwrap();
assert_eq!(res.can_execute, true);
let res = query_can_execute(deps.as_ref(), spender.clone(), staking_withdraw_msg.clone())
.unwrap();
assert_eq!(res.can_execute, false);

// random person cannot do anything
let res = query_can_send(deps.as_ref(), anyone.clone(), send_msg.clone()).unwrap();
assert_eq!(res.can_send, false);
let res = query_can_send(deps.as_ref(), anyone.clone(), send_msg_large.clone()).unwrap();
assert_eq!(res.can_send, false);
let res = query_can_execute(deps.as_ref(), anyone.clone(), send_msg.clone()).unwrap();
assert_eq!(res.can_execute, false);
let res = query_can_execute(deps.as_ref(), anyone.clone(), send_msg_large.clone()).unwrap();
assert_eq!(res.can_execute, false);
let res =
query_can_send(deps.as_ref(), anyone.clone(), staking_delegate_msg.clone()).unwrap();
assert_eq!(res.can_send, false);
query_can_execute(deps.as_ref(), anyone.clone(), staking_delegate_msg.clone()).unwrap();
assert_eq!(res.can_execute, false);
let res =
query_can_send(deps.as_ref(), anyone.clone(), staking_withdraw_msg.clone()).unwrap();
assert_eq!(res.can_send, false);
query_can_execute(deps.as_ref(), anyone.clone(), staking_withdraw_msg.clone()).unwrap();
assert_eq!(res.can_execute, false);
}
}
4 changes: 2 additions & 2 deletions contracts/cw1-subkeys/src/msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,9 @@ where
/// Returns PermissionsInfo
Permissions { spender: HumanAddr },
/// Checks permissions of the caller on this proxy.
/// If CanSend returns true then a call to `Execute` with the same message,
/// If CanExecute returns true then a call to `Execute` with the same message,
/// before any further state changes, should also succeed.
CanSend {
CanExecute {
sender: HumanAddr,
msg: CosmosMsg<T>,
},
Expand Down
4 changes: 2 additions & 2 deletions contracts/cw1-whitelist/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "cw1-whitelist"
version = "0.3.2"
version = "0.4.0"
authors = ["Ethan Frey <ethanfrey@users.noreply.github.com>"]
edition = "2018"
description = "Implementation of an proxy contract using a whitelist"
Expand All @@ -19,7 +19,7 @@ library = []

[dependencies]
cw0 = { path = "../../packages/cw0", version = "0.3.2" }
cw1 = { path = "../../packages/cw1", version = "0.3.2" }
cw1 = { path = "../../packages/cw1", version = "0.4.0" }
cw2 = { path = "../../packages/cw2", version = "0.3.2" }
cosmwasm-std = { version = "0.12.0-alpha2", features = ["iterator"] }
cosmwasm-storage = { version = "0.12.0-alpha2", features = ["iterator"] }
Expand Down
6 changes: 3 additions & 3 deletions contracts/cw1-whitelist/schema/query_msg.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@
}
},
{
"description": "Checks permissions of the caller on this proxy. If CanSend returns true then a call to `Execute` with the same message, before any further state changes, should also succeed.",
"description": "Checks permissions of the caller on this proxy. If CanExecute returns true then a call to `Execute` with the same message, before any further state changes, should also succeed.",
"type": "object",
"required": [
"can_send"
"can_execute"
],
"properties": {
"can_send": {
"can_execute": {
"type": "object",
"required": [
"msg",
Expand Down
34 changes: 17 additions & 17 deletions contracts/cw1-whitelist/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use cosmwasm_std::{
attr, to_binary, Api, Binary, CanonicalAddr, CosmosMsg, Deps, DepsMut, Empty, Env,
HandleResponse, HumanAddr, InitResponse, MessageInfo, StdResult,
};
use cw1::CanSendResponse;
use cw1::CanExecuteResponse;
use cw2::set_contract_version;

use crate::error::ContractError;
Expand Down Expand Up @@ -61,7 +61,7 @@ pub fn handle_execute<T>(
where
T: Clone + fmt::Debug + PartialEq + JsonSchema,
{
if !can_send(deps.as_ref(), &info.sender)? {
if !can_execute(deps.as_ref(), &info.sender)? {
Err(ContractError::Unauthorized {})
} else {
let mut res = HandleResponse::default();
Expand Down Expand Up @@ -108,7 +108,7 @@ pub fn handle_update_admins(
}
}

fn can_send(deps: Deps, sender: &HumanAddr) -> StdResult<bool> {
fn can_execute(deps: Deps, sender: &HumanAddr) -> StdResult<bool> {
let cfg = admin_list_read(deps.storage).load()?;
let can = cfg.is_admin(&deps.api.canonical_address(sender)?);
Ok(can)
Expand All @@ -117,7 +117,7 @@ fn can_send(deps: Deps, sender: &HumanAddr) -> StdResult<bool> {
pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult<Binary> {
match msg {
QueryMsg::AdminList {} => to_binary(&query_admin_list(deps)?),
QueryMsg::CanSend { sender, msg } => to_binary(&query_can_send(deps, sender, msg)?),
QueryMsg::CanExecute { sender, msg } => to_binary(&query_can_execute(deps, sender, msg)?),
}
}

Expand All @@ -129,13 +129,13 @@ pub fn query_admin_list(deps: Deps) -> StdResult<AdminListResponse> {
})
}

pub fn query_can_send(
pub fn query_can_execute(
deps: Deps,
sender: HumanAddr,
_msg: CosmosMsg,
) -> StdResult<CanSendResponse> {
Ok(CanSendResponse {
can_send: can_send(deps, &sender)?,
) -> StdResult<CanExecuteResponse> {
Ok(CanExecuteResponse {
can_execute: can_execute(deps, &sender)?,
})
}

Expand Down Expand Up @@ -275,7 +275,7 @@ mod tests {
}

#[test]
fn can_send_query_works() {
fn can_execute_query_works() {
let mut deps = mock_dependencies(&[]);

let alice = HumanAddr::from("alice");
Expand Down Expand Up @@ -303,19 +303,19 @@ mod tests {
});

// owner can send
let res = query_can_send(deps.as_ref(), alice.clone(), send_msg.clone()).unwrap();
assert_eq!(res.can_send, true);
let res = query_can_execute(deps.as_ref(), alice.clone(), send_msg.clone()).unwrap();
assert_eq!(res.can_execute, true);

// owner can stake
let res = query_can_send(deps.as_ref(), bob.clone(), staking_msg.clone()).unwrap();
assert_eq!(res.can_send, true);
let res = query_can_execute(deps.as_ref(), bob.clone(), staking_msg.clone()).unwrap();
assert_eq!(res.can_execute, true);

// anyone cannot send
let res = query_can_send(deps.as_ref(), anyone.clone(), send_msg.clone()).unwrap();
assert_eq!(res.can_send, false);
let res = query_can_execute(deps.as_ref(), anyone.clone(), send_msg.clone()).unwrap();
assert_eq!(res.can_execute, false);

// anyone cannot stake
let res = query_can_send(deps.as_ref(), anyone.clone(), staking_msg.clone()).unwrap();
assert_eq!(res.can_send, false);
let res = query_can_execute(deps.as_ref(), anyone.clone(), staking_msg.clone()).unwrap();
assert_eq!(res.can_execute, false);
}
}
4 changes: 2 additions & 2 deletions contracts/cw1-whitelist/src/msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ where
/// Shows all admins and whether or not it is mutable
AdminList {},
/// Checks permissions of the caller on this proxy.
/// If CanSend returns true then a call to `Execute` with the same message,
/// If CanExecute returns true then a call to `Execute` with the same message,
/// before any further state changes, should also succeed.
CanSend {
CanExecute {
sender: HumanAddr,
msg: CosmosMsg<T>,
},
Expand Down
2 changes: 1 addition & 1 deletion packages/cw1/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "cw1"
version = "0.3.2"
version = "0.4.0"
authors = ["Ethan Frey <ethanfrey@users.noreply.github.com>"]
edition = "2018"
description = "Definition and types for the CosmWasm-1 interface"
Expand Down
6 changes: 3 additions & 3 deletions packages/cw1/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ before re-dispatching all those messages from the contract address.

### Queries

`CanSend{sender, msg}` - This accepts one `CosmosMsg` and checks permissions,
returning true or false based on the permissions. If `CanSend` returns true
`CanExecute{sender, msg}` - This accepts one `CosmosMsg` and checks permissions,
returning true or false based on the permissions. If `CanExecute` returns true
then a call to `Execute` from that sender, with the same message,
before any further state changes, should also succeed. This can be used
to dynamically provide some client info on a generic cw1 contract without
knowing the extension details. (eg. detect if they can send coins or stake)
knowing the extension details. (eg. detect if they can send coins or stake)
Loading