Skip to content

Commit

Permalink
feat: switch how to do dynamic link and validate interface to solve r…
Browse files Browse the repository at this point in the history
…ust/Go pointer sharing issue (#283)

* feat: improve contracts using dynamic link for test new dynamic link functions

* feat: change how to dynamic link and validate interface

* chore: cargo fmt

* chore: cargo fmt

* ci: update rust-toolchain version in ci tests according to latest dynamic link branch

* chore: cargo schema on events contract

* chore: cargo clippy

* chore: cargo clippy for dynamic-caller-contract

* test: remove verbose tests for dynamic link

some tests in vm/dynamic_link.rs are testing mock.rs's call_callable point.
this is verbose, and this mock will be removed in #273.
so this commit removes these tests.
  • Loading branch information
loloicci committed Apr 11, 2023
1 parent f3d7757 commit 6ce2d99
Show file tree
Hide file tree
Showing 10 changed files with 593 additions and 583 deletions.
3 changes: 3 additions & 0 deletions contracts/dynamic-callee-contract/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ mod callable_points {
env
}

#[callable_point]
fn do_nothing(_deps: Deps, _env: Env) {}

#[callable_point]
fn do_panic(_deps: Deps, _env: Env) {
panic!();
Expand Down
39 changes: 34 additions & 5 deletions contracts/dynamic-caller-contract/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ trait Callee: Contract {
fn pong_with_tuple_takes_2_args(&self, input1: String, input2: i32) -> (String, i32);
fn pong_env(&self) -> Env;
fn reentrancy(&self, addr: Addr);
fn do_nothing(&self);
fn do_panic(&self);
}

Expand Down Expand Up @@ -64,6 +65,8 @@ impl Callee for CalleeContract {
panic!()
}

fn do_nothing(&self) {}

fn do_panic(&self) {
panic!()
}
Expand Down Expand Up @@ -106,7 +109,12 @@ pub fn execute(
}

pub fn try_ping(deps: DepsMut, ping_num: Uint128) -> Result<Response, ContractError> {
let address: Addr = from_slice(&deps.storage.get(b"dynamic_callee_contract").unwrap())?;
let address: Addr = from_slice(
&deps
.storage
.get(b"dynamic_callee_contract")
.ok_or_else(|| ContractError::Storage("cannot get callee address".to_string()))?,
)?;
let contract = CalleeContract { address };
let pong_ret = contract.pong(ping_num.u128() as u64);
let struct_ret = contract.pong_with_struct(ExampleStruct {
Expand All @@ -115,6 +123,7 @@ pub fn try_ping(deps: DepsMut, ping_num: Uint128) -> Result<Response, ContractEr
});
let tuple_ret = contract.pong_with_tuple((String::from("hello"), 41));
let tuple_ret2 = contract.pong_with_tuple_takes_2_args(String::from("hello"), 41);
contract.do_nothing();

let res = Response::default()
.add_attribute("returned_pong", pong_ret.to_string())
Expand All @@ -138,29 +147,49 @@ pub fn try_ping(deps: DepsMut, ping_num: Uint128) -> Result<Response, ContractEr
pub fn try_re_entrancy(deps: DepsMut, env: Env) -> Result<Response, ContractError> {
// It will be tried to call the should_never_be_called function below.
// But, should be blocked by VM host side normally because it's a reentrancy case.
let address = from_slice(&deps.storage.get(b"dynamic_callee_contract").unwrap())?;
let address = from_slice(
&deps
.storage
.get(b"dynamic_callee_contract")
.ok_or_else(|| ContractError::Storage("cannot get callee address".to_string()))?,
)?;
let contract = CalleeContract { address };
contract.reentrancy(env.contract.address);
Ok(Response::default())
}

pub fn try_do_panic(deps: DepsMut, _env: Env) -> Result<Response, ContractError> {
let address = from_slice(&deps.storage.get(b"dynamic_callee_contract").unwrap())?;
let address = from_slice(
&deps
.storage
.get(b"dynamic_callee_contract")
.ok_or_else(|| ContractError::Storage("cannot get callee address".to_string()))?,
)?;
let contract = CalleeContract { address };
contract.do_panic();
Ok(Response::default())
}

pub fn try_validate_interface(deps: Deps, _env: Env) -> Result<Response, ContractError> {
let address = from_slice(&deps.storage.get(b"dynamic_callee_contract").unwrap())?;
let address = from_slice(
&deps
.storage
.get(b"dynamic_callee_contract")
.ok_or_else(|| ContractError::Storage("cannot get callee address".to_string()))?,
)?;
let contract = CalleeContract { address };
contract.validate_interface(deps)?;
Ok(Response::default())
}

// should error
pub fn try_validate_interface_err(deps: Deps, _env: Env) -> Result<Response, ContractError> {
let address = from_slice(&deps.storage.get(b"dynamic_callee_contract").unwrap())?;
let address = from_slice(
&deps
.storage
.get(b"dynamic_callee_contract")
.ok_or_else(|| ContractError::Storage("cannot get callee address".to_string()))?,
)?;
let err_interface: Vec<wasmer_types::ExportType<wasmer_types::FunctionType>> =
vec![wasmer_types::ExportType::new(
"not_exist",
Expand Down
3 changes: 3 additions & 0 deletions contracts/dynamic-caller-contract/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ pub enum ContractError {
#[error("{0}")]
Std(#[from] StdError),

#[error("Storage: {0}")]
Storage(String),

#[error("Unauthorized")]
Unauthorized {},
// Add any other custom errors you like here.
Expand Down
5 changes: 5 additions & 0 deletions contracts/dynamic-caller-contract/tests/integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ fn required_imports() -> Vec<(String, String, FunctionType)> {
module_name.to_string(),
([Type::I32], [Type::I32]).into(),
),
(
String::from("do_nothing"),
module_name.to_string(),
([Type::I32], []).into(),
),
(
String::from("do_panic"),
module_name.to_string(),
Expand Down
Loading

0 comments on commit 6ce2d99

Please sign in to comment.