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

Keep controllers' model private #204

Merged
merged 2 commits into from
Dec 21, 2020
Merged
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
12 changes: 2 additions & 10 deletions contracts/cw4-stake/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use cw4::{
use cw_storage_plus::Bound;

use crate::error::ContractError;
use crate::msg::{ClaimsResponse, HandleMsg, InitMsg, QueryMsg, StakedResponse};
use crate::msg::{HandleMsg, InitMsg, QueryMsg, StakedResponse};
use crate::state::{Config, ADMIN, CLAIMS, CONFIG, HOOKS, MEMBERS, STAKE, TOTAL};

// version info for migration info
Expand Down Expand Up @@ -241,14 +241,6 @@ fn query_total_weight(deps: Deps) -> StdResult<TotalWeightResponse> {
Ok(TotalWeightResponse { weight })
}

pub fn query_claims(deps: Deps, address: HumanAddr) -> StdResult<ClaimsResponse> {
let address_raw = deps.api.canonical_address(&address)?;
let claims = CLAIMS
.may_load(deps.storage, &address_raw)?
.unwrap_or_default();
Ok(ClaimsResponse { claims })
}

pub fn query_staked(deps: Deps, address: HumanAddr) -> StdResult<StakedResponse> {
let address_raw = deps.api.canonical_address(&address)?;
let stake = STAKE
Expand Down Expand Up @@ -543,7 +535,7 @@ mod tests {
}

fn get_claims<U: Into<HumanAddr>>(deps: Deps, addr: U) -> Vec<Claim> {
query_claims(deps, addr.into()).unwrap().claims
CLAIMS.query_claims(deps, addr.into()).unwrap().claims
}

#[test]
Expand Down
17 changes: 3 additions & 14 deletions packages/controllers/src/admin.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use std::ops::Deref;
use thiserror::Error;

use cosmwasm_std::{
Expand Down Expand Up @@ -29,16 +28,6 @@ pub enum AdminError {
// state/logic
pub struct Admin<'a>(Item<'a, Option<CanonicalAddr>>);

// allow easy access to the basic Item operations if desired
// TODO: reconsider if we need this here, maybe only for maps?
impl<'a> Deref for Admin<'a> {
type Target = Item<'a, Option<CanonicalAddr>>;

fn deref(&self) -> &Self::Target {
&self.0
}
}

// this is the core business logic we expose
impl<'a> Admin<'a> {
pub const fn new(namespace: &'a str) -> Self {
Expand All @@ -47,18 +36,18 @@ impl<'a> Admin<'a> {

pub fn set(&self, deps: DepsMut, admin: Option<HumanAddr>) -> StdResult<()> {
let admin_raw = maybe_canonical(deps.api, admin)?;
self.save(deps.storage, &admin_raw)
self.0.save(deps.storage, &admin_raw)
}

pub fn get(&self, deps: Deps) -> StdResult<Option<HumanAddr>> {
let canon = self.load(deps.storage)?;
let canon = self.0.load(deps.storage)?;
canon.map(|c| deps.api.human_address(&c)).transpose()
}

/// Returns Ok(true) if this is an admin, Ok(false) if not and an Error if
/// we hit an error with Api or Storage usage
pub fn is_admin(&self, deps: Deps, caller: &HumanAddr) -> StdResult<bool> {
match self.load(deps.storage)? {
match self.0.load(deps.storage)? {
Some(owner) => {
let caller_raw = deps.api.canonical_address(caller)?;
Ok(caller_raw == owner)
Expand Down
18 changes: 5 additions & 13 deletions packages/controllers/src/claim.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use serde::{Deserialize, Serialize};
use cosmwasm_std::{BlockInfo, CanonicalAddr, Deps, HumanAddr, StdResult, Storage, Uint128};
use cw0::Expiration;
use cw_storage_plus::Map;
use std::ops::Deref;

// TODO: pull into cw0?
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
Expand All @@ -31,16 +30,6 @@ impl Claim {
// TODO: revisit design (split each claim on own key?)
pub struct Claims<'a>(Map<'a, &'a [u8], Vec<Claim>>);

// allow easy access to the basic Item operations if desired
// TODO: reconsider if we need this here, maybe only for maps?
impl<'a> Deref for Claims<'a> {
type Target = Map<'a, &'a [u8], Vec<Claim>>;

fn deref(&self) -> &Self::Target {
&self.0
}
}

impl<'a> Claims<'a> {
pub const fn new(storage_key: &'a str) -> Self {
Claims(Map::new(storage_key))
Expand All @@ -56,7 +45,7 @@ impl<'a> Claims<'a> {
release_at: Expiration,
) -> StdResult<()> {
// add a claim to this user to get their tokens after the unbonding period
self.update(storage, &addr, |old| -> StdResult<_> {
self.0.update(storage, &addr, |old| -> StdResult<_> {
let mut claims = old.unwrap_or_default();
claims.push(Claim { amount, release_at });
Ok(claims)
Expand All @@ -74,7 +63,7 @@ impl<'a> Claims<'a> {
cap: Option<Uint128>,
) -> StdResult<Uint128> {
let mut to_send = Uint128(0);
self.update(storage, &addr, |claim| -> StdResult<_> {
self.0.update(storage, &addr, |claim| -> StdResult<_> {
let (_send, waiting): (Vec<_>, _) =
claim.unwrap_or_default().iter().cloned().partition(|c| {
// if mature and we can pay fully, then include in _send
Expand All @@ -100,8 +89,11 @@ impl<'a> Claims<'a> {
pub fn query_claims(&self, deps: Deps, address: HumanAddr) -> StdResult<ClaimsResponse> {
let address_raw = deps.api.canonical_address(&address)?;
let claims = self
.0
.may_load(deps.storage, &address_raw)?
.unwrap_or_default();
Ok(ClaimsResponse { claims })
}
}

// TODO: add test coverage
26 changes: 9 additions & 17 deletions packages/controllers/src/hooks.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use std::ops::Deref;
use thiserror::Error;

use cosmwasm_std::{
Expand Down Expand Up @@ -35,47 +34,38 @@ pub enum HookError {
// store all hook addresses in one item. We cannot have many of them before the contract becomes unusable anyway.
pub struct Hooks<'a>(Item<'a, Vec<HumanAddr>>);

// allow easy access to the basic Item operations if desired
// TODO: reconsider if we need this here, maybe only for maps?
impl<'a> Deref for Hooks<'a> {
type Target = Item<'a, Vec<HumanAddr>>;

fn deref(&self) -> &Self::Target {
&self.0
}
}

impl<'a> Hooks<'a> {
pub const fn new(storage_key: &'a str) -> Self {
Hooks(Item::new(storage_key))
}

pub fn add_hook(&self, storage: &mut dyn Storage, addr: HumanAddr) -> Result<(), HookError> {
let mut hooks = self.may_load(storage)?.unwrap_or_default();
let mut hooks = self.0.may_load(storage)?.unwrap_or_default();
if !hooks.iter().any(|h| h == &addr) {
hooks.push(addr);
} else {
return Err(HookError::HookAlreadyRegistered {});
}
Ok(self.save(storage, &hooks)?)
Ok(self.0.save(storage, &hooks)?)
}

pub fn remove_hook(&self, storage: &mut dyn Storage, addr: HumanAddr) -> Result<(), HookError> {
let mut hooks = self.load(storage)?;
let mut hooks = self.0.load(storage)?;
if let Some(p) = hooks.iter().position(|x| x == &addr) {
hooks.remove(p);
} else {
return Err(HookError::HookNotRegistered {});
}
Ok(self.save(storage, &hooks)?)
Ok(self.0.save(storage, &hooks)?)
}

pub fn prepare_hooks<F: Fn(HumanAddr) -> StdResult<CosmosMsg>>(
&self,
storage: &dyn Storage,
prep: F,
) -> StdResult<Vec<CosmosMsg>> {
self.may_load(storage)?
self.0
.may_load(storage)?
.unwrap_or_default()
.into_iter()
.map(prep)
Expand Down Expand Up @@ -109,7 +99,9 @@ impl<'a> Hooks<'a> {
}

pub fn query_hooks(&self, deps: Deps) -> StdResult<HooksResponse> {
let hooks = self.may_load(deps.storage)?.unwrap_or_default();
let hooks = self.0.may_load(deps.storage)?.unwrap_or_default();
Ok(HooksResponse { hooks })
}
}

// TODO: add test coverage