Skip to content

Commit

Permalink
Compiles using ExternRef and ExternMut stubs
Browse files Browse the repository at this point in the history
  • Loading branch information
ethanfrey committed Oct 19, 2020
1 parent a63182e commit 5fe7be4
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 24 deletions.
52 changes: 28 additions & 24 deletions packages/cw0/src/handlers.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
#![allow(dead_code)]
use serde::de::DeserializeOwned;
use std::cell::Cell;
use std::cell::RefCell;
use std::collections::HashMap;

use crate::new_std::{ExternMut, ExternRef};
use cosmwasm_std::{
from_slice, Api, Attribute, BankMsg, Binary, BlockInfo, ContractInfo, ContractResult,
CosmosMsg, Empty, Env, Extern, HandleResponse, HumanAddr, InitResponse, MessageInfo, Querier,
CosmosMsg, Empty, Env, HandleResponse, HumanAddr, InitResponse, MessageInfo, Querier,
QuerierResult, QueryRequest, Storage, SystemError, SystemResult, WasmMsg, WasmQuery,
};
use std::ops::DerefMut;

/// Interface to call into a Contract
pub trait Contract<S, A, Q>
Expand All @@ -18,27 +20,27 @@ where
{
fn handle(
&self,
deps: &mut Extern<S, A, Q>,
deps: ExternMut<S, A, Q>,
env: Env,
info: MessageInfo,
msg: Vec<u8>,
) -> Result<HandleResponse, String>;

fn init(
&self,
deps: &mut Extern<S, A, Q>,
deps: ExternMut<S, A, Q>,
env: Env,
info: MessageInfo,
msg: Vec<u8>,
) -> Result<InitResponse, String>;

fn query(&self, deps: &Extern<S, A, Q>, env: Env, msg: Vec<u8>) -> Result<Binary, String>;
fn query(&self, deps: ExternRef<S, A, Q>, env: Env, msg: Vec<u8>) -> Result<Binary, String>;
}

type ContractFn<S, A, Q, T, R, E> =
fn(deps: &mut Extern<S, A, Q>, env: Env, info: MessageInfo, msg: T) -> Result<R, E>;
fn(deps: ExternMut<S, A, Q>, env: Env, info: MessageInfo, msg: T) -> Result<R, E>;

type QueryFn<S, A, Q, T, E> = fn(deps: &Extern<S, A, Q>, env: Env, msg: T) -> Result<Binary, E>;
type QueryFn<S, A, Q, T, E> = fn(deps: ExternRef<S, A, Q>, env: Env, msg: T) -> Result<Binary, E>;

/// Wraps the exported functions from a contract and provides the normalized format
/// TODO: Allow to customize return values (CustomMsg beyond Empty)
Expand Down Expand Up @@ -93,7 +95,7 @@ where
{
fn handle(
&self,
deps: &mut Extern<S, A, Q>,
deps: ExternMut<S, A, Q>,
env: Env,
info: MessageInfo,
msg: Vec<u8>,
Expand All @@ -105,7 +107,7 @@ where

fn init(
&self,
deps: &mut Extern<S, A, Q>,
deps: ExternMut<S, A, Q>,
env: Env,
info: MessageInfo,
msg: Vec<u8>,
Expand All @@ -115,7 +117,7 @@ where
res.map_err(|e| e.to_string())
}

fn query(&self, deps: &Extern<S, A, Q>, env: Env, msg: Vec<u8>) -> Result<Binary, String> {
fn query(&self, deps: ExternRef<S, A, Q>, env: Env, msg: Vec<u8>) -> Result<Binary, String> {
let msg: T3 = from_slice(&msg).map_err(|e| e.to_string())?;
let res = (self.query_fn)(deps, env, msg);
res.map_err(|e| e.to_string())
Expand All @@ -124,14 +126,14 @@ where

struct ContractData<S: Storage + Default> {
code_id: usize,
storage: Cell<S>,
storage: RefCell<S>,
}

impl<S: Storage + Default> ContractData<S> {
fn new(code_id: usize) -> Self {
ContractData {
code_id,
storage: Cell::new(S::default()),
storage: RefCell::new(S::default()),
}
}
}
Expand Down Expand Up @@ -195,7 +197,7 @@ where
pub fn handle(
&self,
address: HumanAddr,
querier: Q,
querier: &Q,
info: MessageInfo,
msg: Vec<u8>,
) -> Result<HandleResponse, String> {
Expand All @@ -207,7 +209,7 @@ where
pub fn init(
&self,
address: HumanAddr,
querier: Q,
querier: &Q,
info: MessageInfo,
msg: Vec<u8>,
) -> Result<InitResponse, String> {
Expand All @@ -216,9 +218,9 @@ where
})
}

pub fn query(&self, address: HumanAddr, querier: Q, msg: Vec<u8>) -> Result<Binary, String> {
pub fn query(&self, address: HumanAddr, querier: &Q, msg: Vec<u8>) -> Result<Binary, String> {
self.with_storage(querier, address, |handler, deps, env| {
handler.query(deps, env, msg)
handler.query(deps.as_ref(), env, msg)
})
}

Expand All @@ -231,9 +233,9 @@ where
}
}

fn with_storage<F, T>(&self, querier: Q, address: HumanAddr, action: F) -> Result<T, String>
fn with_storage<F, T>(&self, querier: &Q, address: HumanAddr, action: F) -> Result<T, String>
where
F: FnOnce(&Box<dyn Contract<S, A, Q>>, &mut Extern<S, A, Q>, Env) -> Result<T, String>,
F: FnOnce(&Box<dyn Contract<S, A, Q>>, ExternMut<S, A, Q>, Env) -> Result<T, String>,
{
let contract = self
.contracts
Expand All @@ -245,14 +247,16 @@ where
.ok_or_else(|| "Unregistered code id".to_string())?;
let env = self.get_env(address);

let storage = contract.storage.take();
let mut deps = Extern {
storage,
api: self.api,
let mut storage = contract
.storage
.try_borrow_mut()
.map_err(|e| format!("Double-borrowing mutable storage - re-entrancy?: {}", e))?;
let deps = ExternMut {
storage: storage.deref_mut(),
api: &self.api,
querier,
};
let res = action(handler, &mut deps, env);
contract.storage.replace(deps.storage);
let res = action(handler, deps, env);
res
}
}
Expand Down
1 change: 1 addition & 0 deletions packages/cw0/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
mod balance;
mod expiration;
mod handlers;
mod new_std;
mod pagination;

pub use crate::balance::NativeBalance;
Expand Down
49 changes: 49 additions & 0 deletions packages/cw0/src/new_std.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
use cosmwasm_std::{Api, Querier, Storage};

///! some features that should be in cosmwasm_std v0.12 mocked out here for ease
pub struct ExternMut<'a, S: Storage, A: Api, Q: Querier> {
pub storage: &'a mut S,
pub api: &'a A,
pub querier: &'a Q,
}

pub struct ExternRef<'a, S: Storage, A: Api, Q: Querier> {
pub storage: &'a S,
pub api: &'a A,
pub querier: &'a Q,
}

impl<'a, S: Storage, A: Api, Q: Querier> ExternMut<'a, S, A, Q> {
pub fn as_ref(self) -> ExternRef<'a, S, A, Q> {
ExternRef {
storage: self.storage,
api: self.api,
querier: self.querier,
}
}
}

// pub struct Extern<S: Storage, A: Api, Q: Querier> {
// pub storage: S,
// pub api: A,
// pub querier: Q,
// }
//
// impl<S: Storage, A: Api, Q: Querier> Extern<S, A, Q> {
// pub fn as_ref(&'_ self) -> ExternRef<'_, S, A, Q> {
// ExternRef {
// storage: &self.storage,
// api: &self.api,
// querier: &self.querier,
// }
// }
//
// pub fn as_mut(&'_ mut self) -> ExternMut<'_, S, A, Q> {
// ExternMut {
// storage: &mut self.storage,
// api: &self.api,
// querier: &self.querier,
// }
// }
// }

0 comments on commit 5fe7be4

Please sign in to comment.