Skip to content

Commit

Permalink
modified trait implementation according to changes in CosmWasm/cosmwa…
Browse files Browse the repository at this point in the history
  • Loading branch information
Expotential108 committed May 13, 2020
1 parent 517a2ac commit c78e09f
Show file tree
Hide file tree
Showing 9 changed files with 75 additions and 94 deletions.
14 changes: 7 additions & 7 deletions Cargo.lock

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

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ singlepass = ["cosmwasm-vm/default-singlepass"]
cranelift = ["cosmwasm-vm/default-cranelift"]

[dependencies]
cosmwasm-std = { git = "https://github.com/CosmWasm/cosmwasm", rev = "71f643f577184a23b2f1f122531c944f0de94c34", features = ["iterator"]}
cosmwasm-vm = { git = "https://github.com/CosmWasm/cosmwasm", rev = "71f643f577184a23b2f1f122531c944f0de94c34", features = ["iterator"] }
cosmwasm-std = { git = "https://github.com/reuvenpo/cosmwasm", rev = "44ca77e28c675937986dd3469e0e836217a7ad00", features = ["iterator"]}
cosmwasm-vm = { git = "https://github.com/reuvenpo/cosmwasm", rev = "44ca77e28c675937986dd3469e0e836217a7ad00", features = ["iterator"] }
errno = "0.2"
snafu = "0.6.3"
serde_json = "1.0"
Expand Down
27 changes: 10 additions & 17 deletions src/api.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use cosmwasm_std::{generic_err, invalid_utf8, Api, Binary, CanonicalAddr, HumanAddr, StdResult};
use cosmwasm_std::{Binary, CanonicalAddr, HumanAddr};
use cosmwasm_vm::{Api, FfiError, FfiResult};

use crate::error::GoResult;
use crate::memory::Buffer;
Expand Down Expand Up @@ -34,20 +35,16 @@ pub struct GoApi {
unsafe impl Send for GoApi {}

impl Api for GoApi {
fn canonical_address(&self, human: &HumanAddr) -> StdResult<CanonicalAddr> {
fn canonical_address(&self, human: &HumanAddr) -> FfiResult<CanonicalAddr> {
let human_bytes = human.as_str().as_bytes();
let human_bytes = Buffer::from_vec(human_bytes.to_vec());
let mut output = Buffer::default();
let go_result: GoResult =
(self.vtable.canonicalize_address)(self.state, human_bytes, &mut output as *mut Buffer)
.into();
let _human = unsafe { human_bytes.consume() };
if !go_result.is_ok() {
return Err(generic_err(format!(
"Go {}: canonical address for {}",
go_result, human
)));
}
let go_result: FfiResult<()> = go_result.into();
go_result?;
let canon = if output.ptr.is_null() {
Vec::new()
} else {
Expand All @@ -58,28 +55,24 @@ impl Api for GoApi {
Ok(CanonicalAddr(Binary(canon)))
}

fn human_address(&self, canonical: &CanonicalAddr) -> StdResult<HumanAddr> {
fn human_address(&self, canonical: &CanonicalAddr) -> FfiResult<HumanAddr> {
let canonical = canonical.as_slice();
let canonical = Buffer::from_vec(canonical.to_vec());
let mut output = Buffer::default();
let go_result: GoResult =
(self.vtable.humanize_address)(self.state, canonical, &mut output as *mut Buffer)
.into();
let canonical = unsafe { canonical.consume() };
if !go_result.is_ok() {
return Err(generic_err(format!(
"Go {}: human address for {:?}",
go_result, canonical
)));
}
let _canonical = unsafe { canonical.consume() };
let go_result: FfiResult<()> = go_result.into();
go_result?;
let result = if output.ptr.is_null() {
Vec::new()
} else {
// We initialize `output` with a null pointer. if it is not null,
// that means it was initialized by the go code, with values generated by `memory::allocate_rust`
unsafe { output.consume() }
};
let human = String::from_utf8(result).map_err(invalid_utf8)?;
let human = String::from_utf8(result).or(Err(FfiError::Other))?;
Ok(HumanAddr(human))
}
}
47 changes: 14 additions & 33 deletions src/db.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::iterator::GoIter;
use cosmwasm_std::{generic_err, ReadonlyStorage, StdResult, Storage};
use cosmwasm_vm::{FfiResult, ReadonlyStorage, Storage};

use crate::error::GoResult;
use crate::memory::Buffer;
Expand Down Expand Up @@ -28,18 +28,14 @@ pub struct DB {
}

impl ReadonlyStorage for DB {
fn get(&self, key: &[u8]) -> StdResult<Option<Vec<u8>>> {
fn get(&self, key: &[u8]) -> FfiResult<Option<Vec<u8>>> {
let key = Buffer::from_vec(key.to_vec());
let mut result_buf = Buffer::default();
let go_result: GoResult =
(self.vtable.read_db)(self.state, key, &mut result_buf as *mut Buffer).into();
let key = unsafe { key.consume() };
if !go_result.is_ok() {
return Err(generic_err(format!(
"Go {}: reading key {:?}",
go_result, key
)));
}
let _key = unsafe { key.consume() };
let go_result: FfiResult<()> = go_result.into();
go_result?;

if result_buf.ptr.is_null() {
return Ok(None);
Expand All @@ -59,7 +55,7 @@ impl ReadonlyStorage for DB {
start: Option<&[u8]>,
end: Option<&[u8]>,
order: cosmwasm_std::Order,
) -> StdResult<Box<dyn Iterator<Item = StdResult<cosmwasm_std::KV>> + 'a>> {
) -> FfiResult<Box<dyn Iterator<Item = FfiResult<cosmwasm_std::KV>> + 'a>> {
// returns nul pointer in Buffer in none, otherwise proper buffer
let start = start
.map(|s| Buffer::from_vec(s.to_vec()))
Expand All @@ -79,41 +75,26 @@ impl ReadonlyStorage for DB {
let _start = unsafe { start.consume() };
let _end = unsafe { end.consume() };

if !go_result.is_ok() {
return Err(generic_err(format!("Go {}: creating iterator", go_result)));
}
let go_result: FfiResult<()> = go_result.into();
go_result?;
Ok(Box::new(iter))
}
}

impl Storage for DB {
fn set(&mut self, key: &[u8], value: &[u8]) -> StdResult<()> {
fn set(&mut self, key: &[u8], value: &[u8]) -> FfiResult<()> {
let key = Buffer::from_vec(key.to_vec());
let value = Buffer::from_vec(value.to_vec());
let go_result: GoResult = (self.vtable.write_db)(self.state, key, value).into();
let key = unsafe { key.consume() };
let _key = unsafe { key.consume() };
let _value = unsafe { value.consume() };
if !go_result.is_ok() {
Err(generic_err(format!(
"Go {}: writing key {:?}",
go_result, key
)))
} else {
Ok(())
}
go_result.into()
}

fn remove(&mut self, key: &[u8]) -> StdResult<()> {
fn remove(&mut self, key: &[u8]) -> FfiResult<()> {
let key = Buffer::from_vec(key.to_vec());
let go_result: GoResult = (self.vtable.remove_db)(self.state, key).into();
let key = unsafe { key.consume() };
if !go_result.is_ok() {
Err(generic_err(format!(
"Go {}: removing key {:?}",
go_result, key
)))
} else {
Ok(())
}
let _key = unsafe { key.consume() };
go_result.into()
}
}
27 changes: 16 additions & 11 deletions src/error/go.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use std::{convert, fmt};
use std::fmt;

use cosmwasm_vm::FfiError;

/// This enum gives names to the status codes returned from Go callbacks to Rust.
///
Expand All @@ -23,7 +25,19 @@ pub enum GoResult {
Other = 4,
}

impl convert::From<i32> for GoResult {
impl From<GoResult> for Result<(), FfiError> {
fn from(other: GoResult) -> Self {
match other {
GoResult::Ok => Ok(()),
GoResult::Panic => Err(FfiError::ForeignPanic),
GoResult::BadArgument => Err(FfiError::BadArgument),
GoResult::OutOfGas => Err(FfiError::OutOfGas),
GoResult::Other => Err(FfiError::Other),
}
}
}

impl From<i32> for GoResult {
fn from(n: i32) -> Self {
use GoResult::*;
// This conversion treats any number that is not otherwise an expected value as `GoError::Other`
Expand All @@ -48,12 +62,3 @@ impl fmt::Display for GoResult {
}
}
}

impl GoResult {
pub fn is_ok(&self) -> bool {
match self {
GoResult::Ok => true,
_ => false,
}
}
}
5 changes: 5 additions & 0 deletions src/error/rust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ pub enum Error {
#[cfg(feature = "backtraces")]
backtrace: snafu::Backtrace,
},
#[snafu(display("Ran out of gas"))]
OutOfGas {
#[cfg(feature = "backtraces")]
backtrace: snafu::Backtrace,
},
}

/// empty_err returns an error with stack trace.
Expand Down
27 changes: 14 additions & 13 deletions src/iterator.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use cosmwasm_std::{generic_err, StdResult, KV};
use cosmwasm_std::KV;

use crate::error::GoResult;
use crate::memory::Buffer;
use cosmwasm_vm::{FfiError, FfiResult};

// this represents something passed in from the caller side of FFI
#[repr(C)]
Expand Down Expand Up @@ -33,13 +34,13 @@ impl Default for GoIter {
}

impl Iterator for GoIter {
type Item = StdResult<KV>;
type Item = FfiResult<KV>;

fn next(&mut self) -> Option<Self::Item> {
let next_db = match self.vtable.next_db {
Some(f) => f,
// TODO: return None here???
None => return Some(Err(generic_err("iterator vtable not set"))),
None => return Some(Err(FfiError::Other)),
};

let mut key_buf = Buffer::default();
Expand All @@ -50,21 +51,21 @@ impl Iterator for GoIter {
&mut value_buf as *mut Buffer,
)
.into();
if !go_result.is_ok() {
return Some(Err(generic_err(format!(
"Go {}: iterator.next()",
go_result
))));
let go_result: FfiResult<()> = go_result.into();
if let Err(err) = go_result {
return Some(Err(err));
}

// TODO: Check if key is null, return none, otherwise, make KV
let okey = unsafe { key_buf.read() };
match okey {
Some(key) => {
// TODO: return error not unwrap??
let value = unsafe { value_buf.read().unwrap() };
let kv = (key.to_vec(), value.to_vec());
Some(Ok(kv))
let value = unsafe { value_buf.read() };
if let Some(value) = value {
let kv = (key.to_vec(), value.to_vec());
Some(Ok(kv))
} else {
Some(Err(FfiError::Other))
}
}
None => None,
}
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use std::str::from_utf8;

use crate::error::{clear_error, handle_c_error, set_error};
use crate::error::{empty_err, EmptyArg, Error, Panic, Utf8Err, WasmErr};
use cosmwasm_std::Extern;
use cosmwasm_vm::Extern;
use cosmwasm_vm::{call_handle_raw, call_init_raw, call_query_raw, CosmCache};

#[repr(C)]
Expand Down
16 changes: 6 additions & 10 deletions src/querier.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use cosmwasm_std::{Querier, QuerierResult, SystemError};
use cosmwasm_std::SystemError;
use cosmwasm_vm::{FfiResult, Querier, QuerierResult};

use crate::error::GoResult;
use crate::memory::Buffer;
Expand Down Expand Up @@ -35,18 +36,13 @@ impl Querier for GoQuerier {
(self.vtable.query_external)(self.state, request, &mut result_buf as *mut Buffer)
.into();
let _request = unsafe { request.consume() };
if !go_result.is_ok() {
return Err(SystemError::InvalidRequest {
error: format!("Go {}: making query", go_result),
});
}
let go_result: FfiResult<()> = go_result.into();
go_result?;

let bin_result = unsafe { result_buf.consume() };
match serde_json::from_slice(&bin_result) {
Ok(v) => v,
Err(e) => Err(SystemError::InvalidRequest {
error: format!("Parsing Go response: {}", e),
}),
Ok(system_result) => Ok(system_result),
Err(_) => Ok(Err(SystemError::InvalidResponse { msg: bin_result })),
}
}
}

0 comments on commit c78e09f

Please sign in to comment.