From 9b7aaff208fbfcb05441bff55d5c4e00ce8946ae Mon Sep 17 00:00:00 2001 From: Nick Hynes Date: Thu, 29 Aug 2019 23:13:25 +0000 Subject: [PATCH 1/7] Remove generics --- bcfs/src/bcfs.rs | 121 +++++++++++----------------- bcfs/src/file.rs | 16 ++-- bcfs/src/tests.rs | 6 +- blockchain-traits/Cargo.toml | 3 + blockchain-traits/src/lib.rs | 85 +++++-------------- memchain/src/block.rs | 28 +++---- memchain/src/lib.rs | 36 ++------- memchain/src/output.rs | 33 +------- memchain/src/pending_transaction.rs | 27 +++---- memchain/src/tests.rs | 28 ++----- oasis-types/Cargo.toml | 1 - oasis-types/src/lib.rs | 36 ++------- 12 files changed, 126 insertions(+), 294 deletions(-) diff --git a/bcfs/src/bcfs.rs b/bcfs/src/bcfs.rs index ec7f1ce..5a566e4 100644 --- a/bcfs/src/bcfs.rs +++ b/bcfs/src/bcfs.rs @@ -1,11 +1,13 @@ use std::{ cell::{Cell, RefCell}, - convert::TryFrom, - io::{Cursor, IoSlice, IoSliceMut, Read, Seek as _, SeekFrom, Write}, + convert::TryFrom as _, + io::{Cursor, IoSlice, IoSliceMut, Read as _, Seek as _, SeekFrom, Write as _}, path::{Path, PathBuf}, + str::FromStr as _, }; -use blockchain_traits::{AccountMeta, Address, PendingTransaction}; +use blockchain_traits::PendingTransaction; +use oasis_types::Address; use wasi_types::{ ErrNo, Fd, FdFlags, FdStat, FileDelta, FileSize, FileStat, FileType, OpenFlags, Rights, Whence, }; @@ -15,32 +17,26 @@ use crate::{ Result, }; -pub struct BCFS { - files: Vec>>, - home_addr: A, - _account_meta: std::marker::PhantomData, +pub struct BCFS { + files: Vec>, + home_addr: Address, } -impl BCFS { +impl BCFS { /// Creates a new ptx FS with a backing `ptx` and hex stringified /// owner address. pub fn new>( - home_addr: A, - // ptx: &mut dyn PendingTransaction
, + home_addr: Address, + // ptx: &mut dyn PendingTransaction< AccountMeta = M>, blockchain_name: S, ) -> Self { Self { files: File::defaults(blockchain_name.as_ref()), home_addr, - _account_meta: std::marker::PhantomData, } } - pub fn prestat( - &mut self, - _ptx: &mut dyn PendingTransaction
, - fd: Fd, - ) -> Result<&Path> { + pub fn prestat(&mut self, _ptx: &mut dyn PendingTransaction, fd: Fd) -> Result<&Path> { match &self.file(fd)?.kind { FileKind::Directory { path } => Ok(path), _ => Err(ErrNo::BadF), @@ -49,7 +45,7 @@ impl BCFS { pub fn open( &mut self, - ptx: &mut dyn PendingTransaction
, + ptx: &mut dyn PendingTransaction, curdir: Fd, path: &Path, open_flags: OpenFlags, @@ -121,10 +117,7 @@ impl BCFS { Ok(fd) } - pub fn tempfile( - &mut self, - _ptx: &mut dyn PendingTransaction
, - ) -> Result { + pub fn tempfile(&mut self, _ptx: &mut dyn PendingTransaction) -> Result { let fd = self.alloc_fd()?; self.files.push(Some(File { kind: FileKind::Temporary, @@ -136,20 +129,12 @@ impl BCFS { Ok(fd) } - pub fn flush( - &mut self, - ptx: &mut dyn PendingTransaction
, - fd: Fd, - ) -> Result<()> { + pub fn flush(&mut self, ptx: &mut dyn PendingTransaction, fd: Fd) -> Result<()> { self.do_flush(ptx, self.file(fd)?); Ok(()) } - pub fn close( - &mut self, - ptx: &mut dyn PendingTransaction
, - fd: Fd, - ) -> Result<()> { + pub fn close(&mut self, ptx: &mut dyn PendingTransaction, fd: Fd) -> Result<()> { self.flush(ptx, fd)?; match self.files.get_mut(fd_usize(fd)) { Some(f) if f.is_some() => { @@ -163,7 +148,7 @@ impl BCFS { /// Removes the file at `path` and returns the number of bytes previously in the file. pub fn unlink( &mut self, - ptx: &mut dyn PendingTransaction
, + ptx: &mut dyn PendingTransaction, curdir: Fd, path: &Path, ) -> Result { @@ -191,7 +176,7 @@ impl BCFS { pub fn seek( &mut self, - ptx: &mut dyn PendingTransaction
, + ptx: &mut dyn PendingTransaction, fd: Fd, offset: FileDelta, whence: Whence, @@ -231,11 +216,7 @@ impl BCFS { } } - pub fn fdstat( - &self, - _ptx: &mut dyn PendingTransaction
, - fd: Fd, - ) -> Result { + pub fn fdstat(&self, _ptx: &mut dyn PendingTransaction, fd: Fd) -> Result { let file = self.file(fd)?; Ok(FdStat { file_type: FileType::RegularFile, @@ -245,20 +226,12 @@ impl BCFS { }) } - pub fn filestat( - &self, - ptx: &dyn PendingTransaction
, - fd: Fd, - ) -> Result { + pub fn filestat(&self, ptx: &dyn PendingTransaction, fd: Fd) -> Result { let file = self.file(fd)?; Self::populate_file(ptx, file, &mut *file.buf.borrow_mut()) } - pub fn tell( - &self, - ptx: &mut dyn PendingTransaction
, - fd: Fd, - ) -> Result { + pub fn tell(&self, ptx: &mut dyn PendingTransaction, fd: Fd) -> Result { let file = self.file(fd)?; let mut buf = file.buf.borrow_mut(); if let FileCache::Absent(SeekFrom::End(_)) = &*buf { @@ -276,7 +249,7 @@ impl BCFS { pub fn read_vectored( &mut self, - ptx: &mut dyn PendingTransaction
, + ptx: &mut dyn PendingTransaction, fd: Fd, bufs: &mut [IoSliceMut], ) -> Result { @@ -285,7 +258,7 @@ impl BCFS { pub fn pread_vectored( &self, - ptx: &mut dyn PendingTransaction
, + ptx: &mut dyn PendingTransaction, fd: Fd, bufs: &mut [IoSliceMut], offset: FileSize, @@ -295,7 +268,7 @@ impl BCFS { pub fn write_vectored( &mut self, - ptx: &mut dyn PendingTransaction
, + ptx: &mut dyn PendingTransaction, fd: Fd, bufs: &[IoSlice], ) -> Result { @@ -304,7 +277,7 @@ impl BCFS { pub fn pwrite_vectored( &mut self, - ptx: &mut dyn PendingTransaction
, + ptx: &mut dyn PendingTransaction, fd: Fd, bufs: &[IoSlice], offset: FileSize, @@ -314,7 +287,7 @@ impl BCFS { pub fn renumber( &mut self, - _ptx: &mut dyn PendingTransaction
, + _ptx: &mut dyn PendingTransaction, fd: Fd, new_fd: Fd, ) -> Result<()> { @@ -327,7 +300,7 @@ impl BCFS { } } - pub fn sync(&mut self, ptx: &mut dyn PendingTransaction
) { + pub fn sync(&mut self, ptx: &mut dyn PendingTransaction) { // flush stdout and stderr for file in self.files[1..=3].iter() { if let Some(file) = file { @@ -353,8 +326,8 @@ fn seekfrom_from_offset_whence(offset: FileDelta, whence: Whence) -> Result BCFS { - fn canonicalize_path(&self, curdir: Fd, path: &Path) -> Result<(Option, PathBuf)> { +impl BCFS { + fn canonicalize_path(&self, curdir: Fd, path: &Path) -> Result<(Option
, PathBuf)> { use std::path::Component; if path.has_root() { @@ -372,13 +345,15 @@ impl BCFS { let addr = if curdir_fileno == CHAIN_DIR_FILENO { match comps.peek() { - Some(Component::Normal(maybe_addr)) => match maybe_addr.to_str().map(A::from_str) { - Some(Ok(addr)) => { - comps.next(); - Some(addr) + Some(Component::Normal(maybe_addr)) => { + match maybe_addr.to_str().map(Address::from_str) { + Some(Ok(addr)) => { + comps.next(); + Some(addr) + } + _ => None, } - _ => None, - }, + } Some(Component::Prefix(_)) | Some(Component::RootDir) => return Err(ErrNo::NoEnt), _ => None, } @@ -417,14 +392,14 @@ impl BCFS { } } - fn file(&self, fd: Fd) -> Result<&File> { + fn file(&self, fd: Fd) -> Result<&File> { match self.files.get(fd_usize(fd)) { Some(Some(file)) => Ok(file), _ => Err(ErrNo::BadF), } } - fn file_mut(&mut self, fd: Fd) -> Result<&mut File> { + fn file_mut(&mut self, fd: Fd) -> Result<&mut File> { match self .files .get_mut(usize::try_from(u64::from(fd)).map_err(|_| ErrNo::BadF)?) @@ -457,8 +432,8 @@ impl BCFS { } fn populate_file( - ptx: &dyn PendingTransaction
, - file: &File, + ptx: &dyn PendingTransaction, + file: &File, cache: &mut FileCache, ) -> Result { let file_size = match cache { @@ -471,7 +446,7 @@ impl BCFS { None => return Err(ErrNo::NoEnt), }, FileKind::Balance { addr } => match ptx.account_meta_at(&addr) { - Some(meta) => meta.balance().to_le_bytes().to_vec(), + Some(meta) => meta.balance.to_le_bytes().to_vec(), None => return Err(ErrNo::NoEnt), }, FileKind::Regular { key } => match ptx.state().get(&key) { @@ -509,7 +484,7 @@ impl BCFS { fn do_pread_vectored( &self, - ptx: &mut dyn PendingTransaction
, + ptx: &mut dyn PendingTransaction, fd: Fd, bufs: &mut [IoSliceMut], offset: Option, @@ -544,7 +519,7 @@ impl BCFS { fn do_pwrite_vectored( &mut self, - ptx: &mut dyn PendingTransaction
, + ptx: &mut dyn PendingTransaction, fd: Fd, bufs: &[IoSlice], offset: Option, @@ -581,11 +556,7 @@ impl BCFS { Ok(nbytes) } - fn do_flush( - &self, - ptx: &mut dyn PendingTransaction
, - file: &File, - ) { + fn do_flush(&self, ptx: &mut dyn PendingTransaction, file: &File) { if !file.dirty.get() { return; } @@ -616,7 +587,7 @@ impl BCFS { }) = f { let f = f.as_ref().unwrap(); - if key != f_key || f as *const File == file as *const File { + if key != f_key || f as *const File == file as *const File { continue; } let mut f_buf = f.buf.borrow_mut(); diff --git a/bcfs/src/file.rs b/bcfs/src/file.rs index 1958d66..d482549 100644 --- a/bcfs/src/file.rs +++ b/bcfs/src/file.rs @@ -4,11 +4,11 @@ use std::{ path::PathBuf, }; -use blockchain_traits::Address; +use oasis_types::Address; use wasi_types::{FdFlags, FileStat}; -pub struct File { - pub kind: FileKind, +pub struct File { + pub kind: FileKind, pub flags: FdFlags, @@ -27,19 +27,19 @@ pub enum FileCache { Present(Cursor>), } -pub enum FileKind { +pub enum FileKind { Stdin, Stdout, Stderr, Log, Temporary, Regular { key: Vec }, - Balance { addr: A }, - Bytecode { addr: A }, + Balance { addr: Address }, + Bytecode { addr: Address }, Directory { path: PathBuf }, } -impl FileKind { +impl FileKind { pub fn is_log(&self) -> bool { match self { FileKind::Log => true, @@ -88,7 +88,7 @@ macro_rules! special_file_ctor { } } -impl File { +impl File { special_file_ctor!(Stdin, Stdout, Stderr); } diff --git a/bcfs/src/tests.rs b/bcfs/src/tests.rs index dfc9e76..fbd96d8 100644 --- a/bcfs/src/tests.rs +++ b/bcfs/src/tests.rs @@ -9,7 +9,7 @@ use std::{ use blockchain_traits::{Blockchain, TransactionOutcome}; use memchain::{Account, Memchain}; -use oasis_types::{AccountMeta, Address}; +use oasis_types::Address; use wasi_types::{ErrNo, Fd, FdFlags, OpenFlags, Whence}; use crate::BCFS; @@ -24,9 +24,7 @@ fn giga(val: u64) -> u64 { val * 1_000_000_000 } -fn create_memchain( - mains: Vec>, -) -> impl Blockchain
{ +fn create_memchain(mains: Vec>) -> impl Blockchain { let genesis_state = mains .into_iter() .enumerate() diff --git a/blockchain-traits/Cargo.toml b/blockchain-traits/Cargo.toml index 89c3d3b..a9d12dc 100644 --- a/blockchain-traits/Cargo.toml +++ b/blockchain-traits/Cargo.toml @@ -8,3 +8,6 @@ description = "A minimal description of a programmable blockchain." repository = "https://github.com/oasislabs/oasis-rs.git" readme = "README.md" keywords = ["blockchain"] + +[dependencies] +oasis-types = { path = "../oasis-types", version = "0.2" } diff --git a/blockchain-traits/src/lib.rs b/blockchain-traits/src/lib.rs index 6f427ed..82b8ecb 100644 --- a/blockchain-traits/src/lib.rs +++ b/blockchain-traits/src/lib.rs @@ -1,44 +1,22 @@ #![feature(non_exhaustive)] -pub trait Address: - Eq + Copy + Default + AsRef<[u8]> + std::fmt::Display + std::str::FromStr -{ - fn path_repr(&self) -> String; -} - -pub trait AccountMeta { - fn balance(&self) -> u64; -} +use oasis_types::{AccountMeta, Address, Event}; pub trait Blockchain { - /// Type representing a handle to a service. - type Address: Address; - - /// Account metadata (e.g., balance, expiry) - type AccountMeta: AccountMeta; - /// Returns the name of this blockchain. fn name(&self) -> &str; /// Returns the block at a given height. - fn block( - &self, - height: usize, - ) -> Option<&dyn Block
>; + fn block(&self, height: usize) -> Option<&dyn Block>; /// Returns a reference to the block at the current maximum height. - fn last_block(&self) -> &dyn Block
; + fn last_block(&self) -> &dyn Block; /// Returns a mutable reference to the block at the current maximum height. - fn last_block_mut( - &mut self, - ) -> &mut dyn Block
; + fn last_block_mut(&mut self) -> &mut dyn Block; } pub trait Block { - type Address: Address; - type AccountMeta: AccountMeta; - /// Returns the height of this block. fn height(&self) -> u64; @@ -50,42 +28,39 @@ pub trait Block { #[allow(clippy::too_many_arguments)] fn transact( &mut self, - caller: Self::Address, - callee: Self::Address, - payer: Self::Address, + caller: Address, + callee: Address, + payer: Address, value: u64, input: &[u8], gas: u64, gas_price: u64, - ) -> Box>; + ) -> Box; /// Returns the bytecode stored at `addr` or `None` if the account does not exist. - fn code_at(&self, addr: &Self::Address) -> Option<&[u8]>; + fn code_at(&self, addr: &Address) -> Option<&[u8]>; /// Returns the metadata of the account stored at `addr`, or /// `None` if the account does not exist. - fn account_meta_at(&self, addr: &Self::Address) -> Option; + fn account_meta_at(&self, addr: &Address) -> Option; /// Returns the state of the acount at `addr`, if it exists. - fn state_at(&self, addr: &Self::Address) -> Option<&dyn KVStore>; + fn state_at(&self, addr: &Address) -> Option<&dyn KVStore>; /// Returns the events emitted during the course of this block. - fn events(&self) -> Vec<&dyn Event
>; + fn events(&self) -> Vec<&Event>; /// Returns the receipts of transactions executed in this block. - fn receipts(&self) -> Vec<&dyn Receipt
>; + fn receipts(&self) -> Vec<&dyn Receipt>; } /// Represents the data and functionality available to a smart contract execution. pub trait PendingTransaction { - type Address: Address; - type AccountMeta: AccountMeta; - /// Returns the address of the current contract instance. - fn address(&self) -> &Self::Address; + fn address(&self) -> &Address; /// Returns the address of the sender of the transaction. - fn sender(&self) -> &Self::Address; + fn sender(&self) -> &Address; /// Returns the value sent to the current transaction. fn value(&self) -> u64; @@ -96,12 +71,7 @@ pub trait PendingTransaction { /// Executes a balance-transferring RPC to `callee` with provided input and value. /// The new transaction will inherit the gas parameters and gas payer of the top level /// transaction. The current account will be set as the sender. - fn transact( - &mut self, - callee: Self::Address, - value: u64, - input: &[u8], - ) -> Box>; + fn transact(&mut self, callee: Address, value: u64, input: &[u8]) -> Box; /// Returns data to the calling transaction. fn ret(&mut self, data: &[u8]); @@ -119,11 +89,11 @@ pub trait PendingTransaction { fn state_mut(&mut self) -> &mut dyn KVStoreMut; /// Returns the bytecode stored at `addr` or `None` if the account does not exist. - fn code_at(&self, addr: &Self::Address) -> Option<&[u8]>; + fn code_at(&self, addr: &Address) -> Option<&[u8]>; /// Returns the metadata of the account stored at `addr`, or /// `None` if the account does not exist. - fn account_meta_at(&self, addr: &Self::Address) -> Option; + fn account_meta_at(&self, addr: &Address) -> Option; } /// Interface for a Blockchain-flavored key-value store. @@ -145,17 +115,15 @@ pub trait KVStoreMut: KVStore { } pub trait Receipt { - type Address: Address; + fn caller(&self) -> &Address; - fn caller(&self) -> &Self::Address; - - fn callee(&self) -> &Self::Address; + fn callee(&self) -> &Address; /// Returns the total gas used during the execution of the transaction. fn gas_used(&self) -> u64; /// Returns the events emitted during the transaction. - fn events(&self) -> Vec<&dyn Event
>; + fn events(&self) -> Vec<&Event>; /// Returns the outcome of this transaction. fn outcome(&self) -> TransactionOutcome; @@ -172,17 +140,6 @@ pub trait Receipt { } } -pub trait Event { - type Address: Address; - - /// The address of the contract that emitted this event. - fn emitter(&self) -> &Self::Address; - - fn topics(&self) -> Vec<&[u8]>; - - fn data(&self) -> &[u8]; -} - #[derive(Clone, Copy, PartialEq, Eq, Debug)] #[non_exhaustive] #[repr(u16)] diff --git a/memchain/src/block.rs b/memchain/src/block.rs index 8f3b709..62642ef 100644 --- a/memchain/src/block.rs +++ b/memchain/src/block.rs @@ -1,5 +1,5 @@ use blockchain_traits::TransactionOutcome; -use oasis_types::{AccountMeta, Address}; +use oasis_types::{AccountMeta, Address, Event}; use crate::{output::Receipt, pending_transaction::PendingTransaction, State}; @@ -23,23 +23,20 @@ impl<'bc> Block<'bc> { } impl<'bc> blockchain_traits::Block for Block<'bc> { - type Address = Address; - type AccountMeta = AccountMeta; - fn height(&self) -> u64 { self.height } fn transact( &mut self, - caller: Self::Address, - callee: Self::Address, - payer: Self::Address, + caller: Address, + callee: Address, + payer: Address, value: u64, input: &[u8], gas: u64, gas_price: u64, - ) -> Box> { + ) -> Box { let mut receipt = Receipt { caller, callee, @@ -108,10 +105,7 @@ impl<'bc> blockchain_traits::Block for Block<'bc> { }; if let Some(main) = self.state.get(&callee).unwrap().main { - let ptx: &mut dyn blockchain_traits::PendingTransaction< - Address = Address, - AccountMeta = AccountMeta, - > = &mut pending_transaction; + let ptx: &mut dyn blockchain_traits::PendingTransaction = &mut pending_transaction; let errno = main(unsafe { // Extend the lifetime, as required by the FFI type. // This is only unsafe if the `main` fn stores the pointer, @@ -135,29 +129,29 @@ impl<'bc> blockchain_traits::Block for Block<'bc> { box receipt } - fn code_at(&self, addr: &Self::Address) -> Option<&[u8]> { + fn code_at(&self, addr: &Address) -> Option<&[u8]> { self.state.get(addr).map(|acct| acct.code.as_ref()) } - fn account_meta_at(&self, addr: &Self::Address) -> Option { + fn account_meta_at(&self, addr: &Address) -> Option { self.state.get(addr).map(|acct| AccountMeta { balance: acct.balance, expiry: acct.expiry, }) } - fn state_at(&self, addr: &Self::Address) -> Option<&dyn blockchain_traits::KVStore> { + fn state_at(&self, addr: &Address) -> Option<&dyn blockchain_traits::KVStore> { self.state.get(addr).map(|acct| &**acct as _) } - fn events(&self) -> Vec<&dyn blockchain_traits::Event
> { + fn events(&self) -> Vec<&Event> { self.completed_transactions .iter() .flat_map(|r| blockchain_traits::Receipt::events(r)) .collect() } - fn receipts(&self) -> Vec<&dyn blockchain_traits::Receipt
> { + fn receipts(&self) -> Vec<&dyn blockchain_traits::Receipt> { self.completed_transactions.iter().map(|r| r as _).collect() } } diff --git a/memchain/src/lib.rs b/memchain/src/lib.rs index 8281bf2..32418f6 100644 --- a/memchain/src/lib.rs +++ b/memchain/src/lib.rs @@ -8,16 +8,13 @@ mod pending_transaction; use std::{borrow::Cow, collections::HashMap, convert::TryInto}; use blockchain_traits::Blockchain; -use oasis_types::{AccountMeta, Address}; +use oasis_types::Address; use block::Block; type State<'bc> = HashMap>; -pub type PtxPtr = *const *mut dyn blockchain_traits::PendingTransaction< - Address = Address, - AccountMeta = AccountMeta, ->; +pub type PtxPtr = *const *mut dyn blockchain_traits::PendingTransaction; pub type AccountMain = extern "C" fn(PtxPtr) -> u16; #[derive(Debug)] @@ -53,38 +50,21 @@ impl<'bc> Memchain<'bc> { } impl<'bc> Blockchain for Memchain<'bc> { - type Address = Address; - type AccountMeta = AccountMeta; - fn name(&self) -> &str { &self.name } - fn block( - &self, - height: usize, - ) -> Option< - &dyn blockchain_traits::Block
, - > { - self.blocks.get(height).map(|b| { - b as &dyn blockchain_traits::Block< - Address = Self::Address, - AccountMeta = Self::AccountMeta, - > - }) + fn block(&self, height: usize) -> Option<&dyn blockchain_traits::Block> { + self.blocks + .get(height) + .map(|b| b as &dyn blockchain_traits::Block) } - fn last_block( - &self, - ) -> &dyn blockchain_traits::Block
- { + fn last_block(&self) -> &dyn blockchain_traits::Block { self.blocks.last().unwrap() } - fn last_block_mut( - &mut self, - ) -> &mut dyn blockchain_traits::Block
- { + fn last_block_mut(&mut self) -> &mut dyn blockchain_traits::Block { self.blocks.last_mut().unwrap() } } diff --git a/memchain/src/output.rs b/memchain/src/output.rs index cf5c57a..422582c 100644 --- a/memchain/src/output.rs +++ b/memchain/src/output.rs @@ -1,5 +1,5 @@ use blockchain_traits::TransactionOutcome; -use oasis_types::Address; +use oasis_types::{Address, Event}; #[derive(Clone, Debug)] pub struct Receipt { @@ -13,13 +13,11 @@ pub struct Receipt { } impl blockchain_traits::Receipt for Receipt { - type Address = Address; - - fn caller(&self) -> &Self::Address { + fn caller(&self) -> &Address { &self.caller } - fn callee(&self) -> &Self::Address { + fn callee(&self) -> &Address { &self.callee } @@ -27,7 +25,7 @@ impl blockchain_traits::Receipt for Receipt { self.gas_used } - fn events(&self) -> Vec<&dyn blockchain_traits::Event
> { + fn events(&self) -> Vec<&Event> { self.events.iter().map(|e| e as _).collect() } @@ -39,26 +37,3 @@ impl blockchain_traits::Receipt for Receipt { self.outcome } } - -#[derive(Clone, Debug)] -pub struct Event { - pub emitter: Address, - pub topics: Vec<[u8; 32]>, - pub data: Vec, -} - -impl blockchain_traits::Event for Event { - type Address = Address; - - fn emitter(&self) -> &Self::Address { - &self.emitter - } - - fn topics(&self) -> Vec<&[u8]> { - self.topics.iter().map(AsRef::as_ref).collect() - } - - fn data(&self) -> &[u8] { - self.data.as_slice() - } -} diff --git a/memchain/src/pending_transaction.rs b/memchain/src/pending_transaction.rs index 4cb6879..393f5dd 100644 --- a/memchain/src/pending_transaction.rs +++ b/memchain/src/pending_transaction.rs @@ -1,10 +1,7 @@ use blockchain_traits::TransactionOutcome; -use oasis_types::{AccountMeta, Address}; +use oasis_types::{AccountMeta, Address, Event}; -use crate::{ - output::{Event, Receipt}, - State, -}; +use crate::{output::Receipt, State}; #[derive(Debug)] pub struct PendingTransaction<'bc> { @@ -21,14 +18,11 @@ pub struct PendingTransaction<'bc> { } impl<'bc> blockchain_traits::PendingTransaction for PendingTransaction<'bc> { - type Address = Address; - type AccountMeta = AccountMeta; - - fn address(&self) -> &Self::Address { + fn address(&self) -> &Address { &self.callee } - fn sender(&self) -> &Self::Address { + fn sender(&self) -> &Address { &self.caller } @@ -42,10 +36,10 @@ impl<'bc> blockchain_traits::PendingTransaction for PendingTransaction<'bc> { fn transact( &mut self, - callee: Self::Address, + callee: Address, value: u64, input: &[u8], - ) -> Box> { + ) -> Box { let caller = self.callee; let mut receipt = Receipt { caller, @@ -96,10 +90,7 @@ impl<'bc> blockchain_traits::PendingTransaction for PendingTransaction<'bc> { let main_fn = self.state.get(&callee).unwrap().main; if let Some(main) = main_fn { - let ptx: &mut dyn blockchain_traits::PendingTransaction< - Address = Address, - AccountMeta = AccountMeta, - > = &mut pending_transaction; + let ptx: &mut dyn blockchain_traits::PendingTransaction = &mut pending_transaction; let errno = main(unsafe { // Extend the lifetime, as required by the FFI type. // This is only unsafe if the `main` fn stores the pointer, @@ -162,11 +153,11 @@ impl<'bc> blockchain_traits::PendingTransaction for PendingTransaction<'bc> { .unwrap() } - fn code_at(&self, addr: &Self::Address) -> Option<&[u8]> { + fn code_at(&self, addr: &Address) -> Option<&[u8]> { self.state.get(addr).map(|acct| acct.code.as_ref()) } - fn account_meta_at(&self, addr: &Self::Address) -> Option { + fn account_meta_at(&self, addr: &Address) -> Option { self.state.get(addr).map(|acct| AccountMeta { balance: acct.balance, expiry: acct.expiry, diff --git a/memchain/src/tests.rs b/memchain/src/tests.rs index d39643c..4460e9b 100644 --- a/memchain/src/tests.rs +++ b/memchain/src/tests.rs @@ -13,15 +13,11 @@ fn giga(num: u64) -> u64 { num * 1_000_000_000 } -extern "C" fn nop_main( - _ptx: *const *mut dyn PendingTransaction
, -) -> u16 { +extern "C" fn nop_main(_ptx: *const *mut dyn PendingTransaction) -> u16 { 0 } -extern "C" fn simple_main( - ptx: *const *mut dyn PendingTransaction
, -) -> u16 { +extern "C" fn simple_main(ptx: *const *mut dyn PendingTransaction) -> u16 { let ptx = unsafe { &mut **ptx }; assert_eq!(ptx.sender(), &ADDR_2); @@ -35,17 +31,13 @@ extern "C" fn simple_main( 0 } -extern "C" fn fail_main( - ptx: *const *mut dyn PendingTransaction
, -) -> u16 { +extern "C" fn fail_main(ptx: *const *mut dyn PendingTransaction) -> u16 { let ptx = unsafe { &mut **ptx }; ptx.err(r"¯\_(ツ)_/¯".as_bytes()); 1 } -extern "C" fn subtx_main( - ptx: *const *mut dyn PendingTransaction
, -) -> u16 { +extern "C" fn subtx_main(ptx: *const *mut dyn PendingTransaction) -> u16 { let ptx = unsafe { &mut **ptx }; let subtx = ptx.transact(ADDR_1, 0 /* value */, &ptx.input().to_vec()); @@ -63,13 +55,7 @@ extern "C" fn subtx_main( } fn create_bc<'bc>( - mains: Vec< - Option< - extern "C" fn( - *const *mut dyn PendingTransaction
, - ) -> u16, - >, - >, + mains: Vec u16>>, ) -> Memchain<'bc> { let genesis_state = mains .into_iter() @@ -217,8 +203,8 @@ fn subtx_ok() { let events = bc.last_block().events(); assert_eq!(events.len(), 1); - assert_eq!(events[0].topics(), vec![[42u8; 32]]); - assert_eq!(events[0].data(), &[0, 0, 0]); + assert_eq!(events[0].topics, vec![[42u8; 32]]); + assert_eq!(events[0].data, &[0, 0, 0]); assert_eq!( bc.last_block() diff --git a/oasis-types/Cargo.toml b/oasis-types/Cargo.toml index 28ce74d..cd0e9ab 100644 --- a/oasis-types/Cargo.toml +++ b/oasis-types/Cargo.toml @@ -10,7 +10,6 @@ readme = "README.md" keywords = ["blockchain", "oasis"] [dependencies] -blockchain-traits = { version = "0.2", path = "../blockchain-traits" } hex = "0.3" serde = { version = "1.0", features = ["derive"] } diff --git a/oasis-types/src/lib.rs b/oasis-types/src/lib.rs index 1c9e14a..049d62f 100644 --- a/oasis-types/src/lib.rs +++ b/oasis-types/src/lib.rs @@ -22,6 +22,10 @@ impl Address { pub const fn len() -> usize { std::mem::size_of::() } + + pub fn path_repr(&self) -> String { + hex::encode(self) + } } impl AsRef<[u8]> for Address { @@ -30,12 +34,6 @@ impl AsRef<[u8]> for Address { } } -impl blockchain_traits::Address for Address { - fn path_repr(&self) -> String { - hex::encode(self) - } -} - impl std::str::FromStr for Address { type Err = hex::FromHexError; fn from_str(s: &str) -> Result { @@ -128,39 +126,19 @@ impl ExtStatusCode { pub const NoAccount: ExtStatusCode = ExtStatusCode(3); } +#[derive(Clone, Default, Debug)] pub struct AccountMeta { pub balance: u64, pub expiry: Option, } -impl blockchain_traits::AccountMeta for AccountMeta { - fn balance(&self) -> u64 { - self.balance - } -} - +#[derive(Clone, Default, Debug)] pub struct Event { pub emitter: Address, - pub topics: Vec>, + pub topics: Vec<[u8; 32]>, pub data: Vec, } -impl blockchain_traits::Event for Event { - type Address = Address; - - fn emitter(&self) -> &Self::Address { - &self.emitter - } - - fn topics(&self) -> Vec<&[u8]> { - self.topics.iter().map(Vec::as_slice).collect() - } - - fn data(&self) -> &[u8] { - self.data.as_slice() - } -} - #[cfg(test)] pub mod tests { use super::*; From 8b1550b3d77ffc61c80143cce4cd39e7ec279d99 Mon Sep 17 00:00:00 2001 From: Nick Hynes Date: Sat, 31 Aug 2019 22:34:00 +0000 Subject: [PATCH 2/7] Use u128 for account balances --- bcfs/Cargo.toml | 2 +- bcfs/src/tests.rs | 4 +- blockchain-traits/Cargo.toml | 2 +- blockchain-traits/src/lib.rs | 6 +- memchain/Cargo.toml | 2 +- memchain/src/block.rs | 6 +- memchain/src/lib.rs | 2 +- memchain/src/output.rs | 2 +- memchain/src/pending_transaction.rs | 6 +- memchain/src/tests.rs | 8 +- oasis-test/Cargo.toml | 2 +- oasis-test/src/ext.rs | 6 +- oasis-test/src/lib.rs | 4 +- oasis-types/Cargo.toml | 2 +- oasis-types/src/address.rs | 113 +++++++++++++++++++++++++++ oasis-types/src/lib.rs | 114 +--------------------------- 16 files changed, 143 insertions(+), 138 deletions(-) create mode 100644 oasis-types/src/address.rs diff --git a/bcfs/Cargo.toml b/bcfs/Cargo.toml index 8eb314a..b6c622a 100644 --- a/bcfs/Cargo.toml +++ b/bcfs/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bcfs" -version = "0.2.2" +version = "0.2.3" license = "Apache-2.0" authors = ["Oasis Labs "] edition = "2018" diff --git a/bcfs/src/tests.rs b/bcfs/src/tests.rs index fbd96d8..27d0be0 100644 --- a/bcfs/src/tests.rs +++ b/bcfs/src/tests.rs @@ -20,7 +20,7 @@ const BASE_GAS: u64 = 2100; const GAS_PRICE: u64 = 0; const CHAIN_NAME: &str = "testchain"; -fn giga(val: u64) -> u64 { +fn giga(val: u128) -> u128 { val * 1_000_000_000 } @@ -33,7 +33,7 @@ fn create_memchain(mains: Vec>) -> impl Blockchain ( Address([i as u8; 20]), Cow::Owned(Account { - balance: giga(i as u64), + balance: giga(i as u128), code: format!("\0asm not wasm {}", i).into_bytes(), storage: { let mut storage = HashMap::new(); diff --git a/blockchain-traits/Cargo.toml b/blockchain-traits/Cargo.toml index a9d12dc..dae9900 100644 --- a/blockchain-traits/Cargo.toml +++ b/blockchain-traits/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "blockchain-traits" -version = "0.2.2" +version = "0.2.3" authors = ["Oasis Labs "] edition = "2018" license = "Apache-2.0" diff --git a/blockchain-traits/src/lib.rs b/blockchain-traits/src/lib.rs index 82b8ecb..29cb947 100644 --- a/blockchain-traits/src/lib.rs +++ b/blockchain-traits/src/lib.rs @@ -31,7 +31,7 @@ pub trait Block { caller: Address, callee: Address, payer: Address, - value: u64, + value: u128, input: &[u8], gas: u64, gas_price: u64, @@ -63,7 +63,7 @@ pub trait PendingTransaction { fn sender(&self) -> &Address; /// Returns the value sent to the current transaction. - fn value(&self) -> u64; + fn value(&self) -> u128; /// Returns the input provided by the calling context. fn input(&self) -> &[u8]; @@ -71,7 +71,7 @@ pub trait PendingTransaction { /// Executes a balance-transferring RPC to `callee` with provided input and value. /// The new transaction will inherit the gas parameters and gas payer of the top level /// transaction. The current account will be set as the sender. - fn transact(&mut self, callee: Address, value: u64, input: &[u8]) -> Box; + fn transact(&mut self, callee: Address, value: u128, input: &[u8]) -> Box; /// Returns data to the calling transaction. fn ret(&mut self, data: &[u8]); diff --git a/memchain/Cargo.toml b/memchain/Cargo.toml index 2fb6c35..7238d8d 100644 --- a/memchain/Cargo.toml +++ b/memchain/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "memchain" -version = "0.2.2" +version = "0.2.3" authors = ["Oasis Labs "] edition = "2018" license = "Apache-2.0" diff --git a/memchain/src/block.rs b/memchain/src/block.rs index 62642ef..dc54609 100644 --- a/memchain/src/block.rs +++ b/memchain/src/block.rs @@ -32,7 +32,7 @@ impl<'bc> blockchain_traits::Block for Block<'bc> { caller: Address, callee: Address, payer: Address, - value: u64, + value: u128, input: &[u8], gas: u64, gas_price: u64, @@ -67,11 +67,11 @@ impl<'bc> blockchain_traits::Block for Block<'bc> { Some(payer_acct) => { let payer_acct = payer_acct.to_mut(); let gas_cost = gas * gas_price; - if payer_acct.balance < gas_cost { + if payer_acct.balance < gas_cost as u128 { payer_acct.balance = 0; early_return!(InsufficientFunds); } - payer_acct.balance -= gas_cost; + payer_acct.balance -= gas_cost as u128; } None => early_return!(InvalidCallee), }; diff --git a/memchain/src/lib.rs b/memchain/src/lib.rs index 32418f6..2bcb3e0 100644 --- a/memchain/src/lib.rs +++ b/memchain/src/lib.rs @@ -71,7 +71,7 @@ impl<'bc> Blockchain for Memchain<'bc> { #[derive(Clone, Default, Debug)] pub struct Account { - pub balance: u64, + pub balance: u128, pub code: Vec, pub storage: HashMap, Vec>, pub expiry: Option, diff --git a/memchain/src/output.rs b/memchain/src/output.rs index 422582c..2348a57 100644 --- a/memchain/src/output.rs +++ b/memchain/src/output.rs @@ -6,7 +6,7 @@ pub struct Receipt { pub outcome: TransactionOutcome, pub caller: Address, pub callee: Address, - pub value: u64, + pub value: u128, pub gas_used: u64, pub events: Vec, pub output: Vec, diff --git a/memchain/src/pending_transaction.rs b/memchain/src/pending_transaction.rs index 393f5dd..db910d4 100644 --- a/memchain/src/pending_transaction.rs +++ b/memchain/src/pending_transaction.rs @@ -7,7 +7,7 @@ use crate::{output::Receipt, State}; pub struct PendingTransaction<'bc> { pub caller: Address, pub callee: Address, - pub value: u64, + pub value: u128, pub state: State<'bc>, pub input: Vec, pub outcome: TransactionOutcome, @@ -26,7 +26,7 @@ impl<'bc> blockchain_traits::PendingTransaction for PendingTransaction<'bc> { &self.caller } - fn value(&self) -> u64 { + fn value(&self) -> u128 { self.value } @@ -37,7 +37,7 @@ impl<'bc> blockchain_traits::PendingTransaction for PendingTransaction<'bc> { fn transact( &mut self, callee: Address, - value: u64, + value: u128, input: &[u8], ) -> Box { let caller = self.callee; diff --git a/memchain/src/tests.rs b/memchain/src/tests.rs index 4460e9b..38d0774 100644 --- a/memchain/src/tests.rs +++ b/memchain/src/tests.rs @@ -9,7 +9,7 @@ const ADDR_2: Address = Address([2u8; 20]); const BASE_GAS: u64 = 2100; -fn giga(num: u64) -> u64 { +fn giga(num: u128) -> u128 { num * 1_000_000_000 } @@ -65,7 +65,7 @@ fn create_bc<'bc>( ( Address([i as u8; 20]), Cow::Owned(Account { - balance: giga(i as u64), + balance: giga(i as u128), code: format!("\0asm not wasm {}", i).into_bytes(), storage: { let mut storage = HashMap::new(); @@ -105,7 +105,7 @@ fn transfer() { .transact(ADDR_1, ADDR_2, ADDR_1, value, &Vec::new(), BASE_GAS, 1); assert_eq!( bc.last_block().account_meta_at(&ADDR_1).unwrap().balance, - giga(1) - BASE_GAS - value, + giga(1) - BASE_GAS as u128 - value, ); assert_eq!( bc.last_block().account_meta_at(&ADDR_2).unwrap().balance, @@ -176,7 +176,7 @@ fn revert_tx() { .transact(ADDR_1, ADDR_2, ADDR_2, 10_000, &Vec::new(), BASE_GAS, 1); assert_eq!( bc.last_block().account_meta_at(&ADDR_2).unwrap().balance, - giga(2) - BASE_GAS, + giga(2) - BASE_GAS as u128, ); assert_eq!( bc.last_block().account_meta_at(&ADDR_1).unwrap().balance, diff --git a/oasis-test/Cargo.toml b/oasis-test/Cargo.toml index e61e8f7..8ad1bfe 100644 --- a/oasis-test/Cargo.toml +++ b/oasis-test/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "oasis-test" -version = "0.2.0" +version = "0.2.1" license = "Apache-2.0" description = "A testing framework for Oasis executables." edition = "2018" diff --git a/oasis-test/src/ext.rs b/oasis-test/src/ext.rs index 33f6e4c..e3fa5b3 100644 --- a/oasis-test/src/ext.rs +++ b/oasis-test/src/ext.rs @@ -6,7 +6,7 @@ use oasis_types::{Address, ExtStatusCode}; static oasis_testing: bool = true; #[no_mangle] -pub extern "C" fn oasis_balance(addr: *const Address, balance: *mut u64) -> ExtStatusCode { +pub extern "C" fn oasis_balance(addr: *const Address, balance: *mut u128) -> ExtStatusCode { ExtStatusCode::Success } @@ -73,7 +73,7 @@ pub extern "C" fn oasis_err_len(len: *mut u32) -> ExtStatusCode { #[no_mangle] pub extern "C" fn oasis_transact( callee: *const Address, - value: u64, + value: u128, input: *const u8, input_len: u32, ) -> ExtStatusCode { @@ -91,7 +91,7 @@ pub extern "C" fn oasis_sender(addr: *mut Address) -> ExtStatusCode { } #[no_mangle] -pub extern "C" fn oasis_value(value: *mut u64) -> ExtStatusCode { +pub extern "C" fn oasis_value(value: *mut u128) -> ExtStatusCode { ExtStatusCode::Success } diff --git a/oasis-test/src/lib.rs b/oasis-test/src/lib.rs index 853bc03..dafe368 100644 --- a/oasis-test/src/lib.rs +++ b/oasis-test/src/lib.rs @@ -14,7 +14,7 @@ thread_local! { RefCell::new(Memchain::new("testnet".to_string(), { let mut genesis_state = std::collections::HashMap::new(); genesis_state.insert(SEED_ADDR, std::borrow::Cow::Owned(memchain::Account { - balance: u64::max_value(), + balance: u128::max_value(), ..Default::default() })); genesis_state @@ -22,7 +22,7 @@ thread_local! { static NEXT_ADDR: RefCell = RefCell::new(0); } -pub fn create_account(initial_balance: u64) -> Address { +pub fn create_account(initial_balance: u128) -> Address { MEMCHAIN.with(|memchain| { let mut memchain = memchain.borrow_mut(); diff --git a/oasis-types/Cargo.toml b/oasis-types/Cargo.toml index cd0e9ab..ae72f57 100644 --- a/oasis-types/Cargo.toml +++ b/oasis-types/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "oasis-types" -version = "0.2.0" +version = "0.2.1" authors = ["Oasis Labs "] edition = "2018" license = "Apache-2.0" diff --git a/oasis-types/src/address.rs b/oasis-types/src/address.rs new file mode 100644 index 0000000..2de1869 --- /dev/null +++ b/oasis-types/src/address.rs @@ -0,0 +1,113 @@ +/// A 160-bit little-endian hash address type. +#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Debug, Hash, Serialize)] +#[repr(C)] +#[serde(transparent)] +pub struct Address(pub [u8; 20]); + +impl Address { + /// Creates an `Address` from a little-endian byte array. + pub unsafe fn from_raw(bytes: *const u8) -> Self { + let mut addr = Self::default(); + addr.0 + .copy_from_slice(std::slice::from_raw_parts(bytes, 20)); + addr + } + + pub fn as_ptr(&self) -> *const u8 { + self.0.as_ptr() + } + + // Alias for `mem::size_of::
()`. + pub const fn size() -> usize { + std::mem::size_of::() + } + + pub fn path_repr(&self) -> String { + hex::encode(self) + } +} + +impl AsRef<[u8]> for Address { + fn as_ref(&self) -> &[u8] { + &self.0 + } +} + +impl std::str::FromStr for Address { + type Err = hex::FromHexError; + fn from_str(s: &str) -> Result { + let bytes: Vec = hex::decode(s)?; + if bytes.len() != Address::size() { + return Err(hex::FromHexError::InvalidStringLength); + } + let mut addr = Self::default(); + addr.0.copy_from_slice(&bytes); + Ok(addr) + } +} + +impl std::fmt::Display for Address { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "0x{}", hex::encode(self.0)) + } +} + +impl<'de> serde::de::Deserialize<'de> for Address { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'de>, + { + use serde::de; + + const EXPECTATION: &str = "20 bytes"; + + struct AddressVisitor; + impl<'de> de::Visitor<'de> for AddressVisitor { + type Value = Address; + + fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + f.write_str(EXPECTATION) + } + + fn visit_seq(self, mut seq: V) -> Result + where + V: de::SeqAccess<'de>, + { + let mut addr = Address::default(); + + if let Some(len) = seq.size_hint() { + if len != Address::size() { + return Err(de::Error::invalid_length(len, &EXPECTATION)); + } + } + + let mut i = 0; + loop { + match seq.next_element()? { + Some(el) if i < Address::size() => addr.0[i] = el, + None if i == Address::size() => break, + _ => return Err(de::Error::invalid_length(i, &EXPECTATION)), + } + i += 1; + } + + Ok(addr) + } + + fn visit_bytes(self, value: &[u8]) -> Result + where + E: de::Error, + { + let mut addr = Address::default(); + if value.len() == Address::size() { + addr.0.copy_from_slice(value); + Ok(addr) + } else { + Err(de::Error::invalid_length(value.len(), &EXPECTATION)) + } + } + } + + deserializer.deserialize_any(AddressVisitor) + } +} diff --git a/oasis-types/src/lib.rs b/oasis-types/src/lib.rs index 049d62f..6653440 100644 --- a/oasis-types/src/lib.rs +++ b/oasis-types/src/lib.rs @@ -1,117 +1,9 @@ #[macro_use] extern crate serde; -/// A 160-bit little-endian hash address type. -#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Debug, Hash, Serialize)] -#[repr(C)] -pub struct Address(pub [u8; 20]); - -impl Address { - /// Creates an `Address` from a little-endian byte array. - pub unsafe fn from_raw(bytes: *const u8) -> Self { - let mut addr = Self::default(); - addr.0 - .copy_from_slice(std::slice::from_raw_parts(bytes, 20)); - addr - } - - pub fn as_ptr(&self) -> *const u8 { - self.0.as_ptr() - } - - pub const fn len() -> usize { - std::mem::size_of::() - } - - pub fn path_repr(&self) -> String { - hex::encode(self) - } -} - -impl AsRef<[u8]> for Address { - fn as_ref(&self) -> &[u8] { - &self.0 - } -} - -impl std::str::FromStr for Address { - type Err = hex::FromHexError; - fn from_str(s: &str) -> Result { - let bytes: Vec = hex::decode(s)?; - if bytes.len() != Address::len() { - return Err(hex::FromHexError::InvalidStringLength); - } - let mut addr = Self::default(); - addr.0.copy_from_slice(&bytes); - Ok(addr) - } -} - -impl std::fmt::Display for Address { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "0x{}", hex::encode(self.0)) - } -} - -impl<'de> serde::de::Deserialize<'de> for Address { - fn deserialize(deserializer: D) -> Result - where - D: serde::de::Deserializer<'de>, - { - use serde::de; - - const EXPECTATION: &str = "20 bytes"; - - struct AddressVisitor; - impl<'de> de::Visitor<'de> for AddressVisitor { - type Value = Address; - - fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - f.write_str(EXPECTATION) - } +mod address; - fn visit_seq(self, mut seq: V) -> Result - where - V: de::SeqAccess<'de>, - { - let mut arr = [0; Self::Value::len()]; - - if let Some(len) = seq.size_hint() { - if len != arr.len() { - return Err(de::Error::invalid_length(len, &EXPECTATION)); - } - } - - let mut i = 0; - loop { - match seq.next_element()? { - Some(el) if i < arr.len() => arr[i] = el, - None if i == arr.len() => break, - _ => return Err(de::Error::invalid_length(i, &EXPECTATION)), - } - i += 1; - } - - Ok(Address(arr)) - } - - fn visit_bytes(self, value: &[u8]) -> Result - where - E: de::Error, - { - let mut arr = [0; std::mem::size_of::()]; - if value.len() == arr.len() { - arr.copy_from_slice(value); - Ok(Address(arr)) - } else { - Err(de::Error::invalid_length(value.len(), &EXPECTATION)) - } - } - } - - deserializer.deserialize_any(AddressVisitor) - } -} +pub use address::Address; #[repr(C)] #[derive(PartialEq, Eq)] @@ -128,7 +20,7 @@ impl ExtStatusCode { #[derive(Clone, Default, Debug)] pub struct AccountMeta { - pub balance: u64, + pub balance: u128, pub expiry: Option, } From ecc5ddd4efea6b08090c35b9c22ec4531dc7072b Mon Sep 17 00:00:00 2001 From: Nick Hynes Date: Sat, 31 Aug 2019 22:35:12 +0000 Subject: [PATCH 3/7] Clippy --- memchain/src/block.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/memchain/src/block.rs b/memchain/src/block.rs index dc54609..06bce52 100644 --- a/memchain/src/block.rs +++ b/memchain/src/block.rs @@ -67,11 +67,11 @@ impl<'bc> blockchain_traits::Block for Block<'bc> { Some(payer_acct) => { let payer_acct = payer_acct.to_mut(); let gas_cost = gas * gas_price; - if payer_acct.balance < gas_cost as u128 { + if payer_acct.balance < u128::from(gas_cost) { payer_acct.balance = 0; early_return!(InsufficientFunds); } - payer_acct.balance -= gas_cost as u128; + payer_acct.balance -= u128::from(gas_cost); } None => early_return!(InvalidCallee), }; From 331326bd26db0b454a5507e810999dae15c0de70 Mon Sep 17 00:00:00 2001 From: Nick Hynes Date: Sun, 1 Sep 2019 03:20:36 +0000 Subject: [PATCH 4/7] Fix tests --- oasis-std/src/backend/wasi.rs | 1 - oasis-types/src/address.rs | 47 +++++++++++++++++++++++++++++++++++ oasis-types/src/lib.rs | 47 ----------------------------------- 3 files changed, 47 insertions(+), 48 deletions(-) diff --git a/oasis-std/src/backend/wasi.rs b/oasis-std/src/backend/wasi.rs index 4a63a5a..b80945e 100644 --- a/oasis-std/src/backend/wasi.rs +++ b/oasis-std/src/backend/wasi.rs @@ -6,7 +6,6 @@ use std::{ str::FromStr, }; -use blockchain_traits::Address as _; use libc::{__wasi_errno_t, __wasi_fd_t}; use oasis_types::Address; diff --git a/oasis-types/src/address.rs b/oasis-types/src/address.rs index 2de1869..25cc1d5 100644 --- a/oasis-types/src/address.rs +++ b/oasis-types/src/address.rs @@ -111,3 +111,50 @@ impl<'de> serde::de::Deserialize<'de> for Address { deserializer.deserialize_any(AddressVisitor) } } + +#[cfg(test)] +pub mod tests { + use super::*; + + #[test] + fn deserialize_address_from_array() { + let bytes = [1u8; 20]; + let addr: Address = serde_cbor::from_slice(&serde_cbor::to_vec(&bytes).unwrap()).unwrap(); + assert_eq!(addr.0, bytes); + } + + #[test] + #[should_panic] + fn fail_deserialize_address_from_short_array() { + let bytes = [1u8; 19]; + serde_cbor::from_slice::
(&serde_cbor::to_vec(&bytes).unwrap()).unwrap(); + } + + #[test] + #[should_panic] + fn fail_deserialize_address_from_long_array() { + let bytes = [1u8; 21]; + serde_cbor::from_slice::
(&serde_cbor::to_vec(&bytes).unwrap()).unwrap(); + } + + #[test] + fn deserialize_address_from_slice() { + let bytes = vec![1u8; 20]; + let addr: Address = serde_cbor::from_slice(&serde_cbor::to_vec(&bytes).unwrap()).unwrap(); + assert_eq!(&addr.0, bytes.as_slice()); + } + + #[test] + #[should_panic] + fn fail_deserialize_address_from_short_slice() { + let bytes = vec![1u8; 19]; + serde_cbor::from_slice::
(&serde_cbor::to_vec(&bytes).unwrap()).unwrap(); + } + + #[test] + #[should_panic] + fn fail_deserialize_address_from_long_slice() { + let bytes = vec![1u8; 21]; + serde_cbor::from_slice::
(&serde_cbor::to_vec(&bytes).unwrap()).unwrap(); + } +} diff --git a/oasis-types/src/lib.rs b/oasis-types/src/lib.rs index 6653440..ef2f3a3 100644 --- a/oasis-types/src/lib.rs +++ b/oasis-types/src/lib.rs @@ -30,50 +30,3 @@ pub struct Event { pub topics: Vec<[u8; 32]>, pub data: Vec, } - -#[cfg(test)] -pub mod tests { - use super::*; - - #[test] - fn deserialize_address_from_array() { - let bytes = [1u8; 20]; - let addr: Address = serde_cbor::from_slice(&serde_cbor::to_vec(&bytes).unwrap()).unwrap(); - assert_eq!(addr.0, bytes); - } - - #[test] - #[should_panic] - fn fail_deserialize_address_from_short_array() { - let bytes = [1u8; 19]; - serde_cbor::from_slice::
(&serde_cbor::to_vec(&bytes).unwrap()).unwrap(); - } - - #[test] - #[should_panic] - fn fail_deserialize_address_from_long_array() { - let bytes = [1u8; 21]; - serde_cbor::from_slice::
(&serde_cbor::to_vec(&bytes).unwrap()).unwrap(); - } - - #[test] - fn deserialize_address_from_slice() { - let bytes = vec![1u8; 20]; - let addr: Address = serde_cbor::from_slice(&serde_cbor::to_vec(&bytes).unwrap()).unwrap(); - assert_eq!(&addr.0, bytes.as_slice()); - } - - #[test] - #[should_panic] - fn fail_deserialize_address_from_short_slice() { - let bytes = vec![1u8; 19]; - serde_cbor::from_slice::
(&serde_cbor::to_vec(&bytes).unwrap()).unwrap(); - } - - #[test] - #[should_panic] - fn fail_deserialize_address_from_long_slice() { - let bytes = vec![1u8; 21]; - serde_cbor::from_slice::
(&serde_cbor::to_vec(&bytes).unwrap()).unwrap(); - } -} From f06accd18db4f34f976f64c55fc2ebce9b506bed Mon Sep 17 00:00:00 2001 From: Nick Hynes Date: Sun, 1 Sep 2019 04:18:54 +0000 Subject: [PATCH 5/7] Update wasi backend --- oasis-std/src/backend/ext.rs | 17 ++++++++++------- oasis-std/src/backend/wasi.rs | 27 +++++++++++++++------------ oasis-std/src/exe.rs | 6 +++--- oasis-std/src/lib.rs | 8 ++++---- 4 files changed, 32 insertions(+), 26 deletions(-) diff --git a/oasis-std/src/backend/ext.rs b/oasis-std/src/backend/ext.rs index 9019bad..20c9645 100644 --- a/oasis-std/src/backend/ext.rs +++ b/oasis-std/src/backend/ext.rs @@ -4,7 +4,8 @@ use super::Error; /// @see the `blockchain-traits` crate for descriptions of these methods. extern "C" { - pub fn oasis_balance(addr: *const Address, balance: *mut u64) -> ExtStatusCode; + #[allow(improper_ctypes)] // u128 is just 2 u64s + pub fn oasis_balance(addr: *const Address, balance: *mut u128) -> ExtStatusCode; pub fn oasis_code(addr: *const Address, buf: *mut u8) -> ExtStatusCode; pub fn oasis_code_len(addr: *const Address, len: *mut u32) -> ExtStatusCode; @@ -24,9 +25,10 @@ extern "C" { pub fn oasis_fetch_aad(buf: *mut u8) -> ExtStatusCode; pub fn oasis_aad_len(len: *mut u32) -> ExtStatusCode; + #[allow(improper_ctypes)] // u128 is just 2 u64s pub fn oasis_transact( callee: *const Address, - value: u64, + value: *const u128, input: *const u8, input_len: u32, ) -> ExtStatusCode; @@ -34,7 +36,8 @@ extern "C" { pub fn oasis_address(addr: *mut Address) -> ExtStatusCode; pub fn oasis_sender(addr: *mut Address) -> ExtStatusCode; pub fn oasis_payer(addr: *mut Address) -> ExtStatusCode; - pub fn oasis_value(value: *mut u64) -> ExtStatusCode; + #[allow(improper_ctypes)] // u128 is just 2 u64s + pub fn oasis_value(value: *mut u128) -> ExtStatusCode; pub fn oasis_read(key: *const u8, key_len: u32, value: *mut u8) -> ExtStatusCode; pub fn oasis_read_len(key: *const u8, key_len: u32, value_len: *mut u32) -> ExtStatusCode; @@ -108,13 +111,13 @@ pub fn aad() -> Vec { aad } -pub fn value() -> u64 { +pub fn value() -> u128 { let mut value = 0; ext!(oasis_value(&mut value as *mut _)).unwrap(); value } -pub fn balance(addr: &Address) -> Option { +pub fn balance(addr: &Address) -> Option { let mut balance = 0; ext!(oasis_balance(addr as *const _, &mut balance as *mut _)) .ok() @@ -137,10 +140,10 @@ pub fn code(addr: &Address) -> Option> { .map(|_| code) } -pub fn transact(callee: &Address, value: u64, input: &[u8]) -> Result, Error> { +pub fn transact(callee: &Address, value: u128, input: &[u8]) -> Result, Error> { ext!(oasis_transact( callee as *const _, - value, + &value as *const u128, input.as_ptr(), if input.len() > u32::max_value() as usize { return Err(Error::InvalidInput); diff --git a/oasis-std/src/backend/wasi.rs b/oasis-std/src/backend/wasi.rs index b80945e..72038c1 100644 --- a/oasis-std/src/backend/wasi.rs +++ b/oasis-std/src/backend/wasi.rs @@ -46,17 +46,19 @@ pub fn aad() -> Vec { base64::decode(&std::env::var_os("AAD").unwrap().into_vec()).unwrap() } -pub fn value() -> u64 { - u64::from_str(&std::env::var("VALUE").unwrap()).unwrap() +pub fn value() -> u128 { + u128::from_str(&std::env::var("VALUE").unwrap()).unwrap() } -pub fn balance(addr: &Address) -> Option { - Some(unsafe { - *std::mem::transmute::<*const u8, *const u64>(match fs::read(home(&*addr, "balance")) { - Ok(balance) => balance.as_ptr(), - Err(err) if err.kind() == io::ErrorKind::NotFound => return None, - Err(err) => panic!(err), - }) +pub fn balance(addr: &Address) -> Option { + Some(match fs::read(home(&*addr, "balance")) { + Ok(balance) => { + let mut buf = [0u8; 16]; + buf.copy_from_slice(&balance); + u128::from_le_bytes(buf) + } + Err(err) if err.kind() == io::ErrorKind::NotFound => return None, + Err(err) => panic!(err), }) } @@ -71,21 +73,22 @@ pub fn code(addr: &Address) -> Option> { #[link(wasm_import_module = "wasi_unstable")] extern "C" { #[link_name = "blockchain_transact"] + #[allow(improper_ctypes)] // u128 is just 2 u64s fn __wasi_blockchain_transact( callee_addr: *const u8, - value: u64, + value: *const u128, input: *const u8, input_len: u64, fd: *mut __wasi_fd_t, ) -> __wasi_errno_t; } -pub fn transact(callee: &Address, value: u64, input: &[u8]) -> Result, Error> { +pub fn transact(callee: &Address, value: u128, input: &[u8]) -> Result, Error> { let mut fd: __wasi_fd_t = 0; let errno = unsafe { __wasi_blockchain_transact( callee.0.as_ptr(), - value, + &value as *const u128, input.as_ptr(), input.len() as u64, &mut fd as *mut _, diff --git a/oasis-std/src/exe.rs b/oasis-std/src/exe.rs index 2c50451..8a14317 100644 --- a/oasis-std/src/exe.rs +++ b/oasis-std/src/exe.rs @@ -24,7 +24,7 @@ pub struct Context { pub sender: Option
, #[doc(hidden)] - pub value: Option, + pub value: Option, #[doc(hidden)] pub gas: Option, @@ -78,7 +78,7 @@ impl Context { } /// Returns the value with which this `Context` was created. - pub fn value(&self) -> u64 { + pub fn value(&self) -> u128 { self.value.unwrap_or_else(crate::backend::value) } } @@ -92,7 +92,7 @@ impl Context { } /// Amends a Context with the value that should be transferred to the callee. - pub fn with_value(mut self, value: u64) -> Self { + pub fn with_value(mut self, value: u128) -> Self { self.value = Some(value); self } diff --git a/oasis-std/src/lib.rs b/oasis-std/src/lib.rs index a2a6713..a6b22ac 100644 --- a/oasis-std/src/lib.rs +++ b/oasis-std/src/lib.rs @@ -39,19 +39,19 @@ macro_rules! service { } pub trait AddressExt { - fn transfer(&self, value: u64) -> Result<(), crate::backend::Error>; + fn transfer(&self, value: u128) -> Result<(), crate::backend::Error>; - fn balance(&self) -> u64; + fn balance(&self) -> u128; fn code(&self) -> Vec; } impl AddressExt for Address { - fn transfer(&self, value: u64) -> Result<(), crate::backend::Error> { + fn transfer(&self, value: u128) -> Result<(), crate::backend::Error> { crate::backend::transact(self, value, &[]).map(|_| ()) } - fn balance(&self) -> u64 { + fn balance(&self) -> u128 { crate::backend::balance(self).unwrap() } From 922daccb47f3b1d68040d856fc0b45557fd4f27f Mon Sep 17 00:00:00 2001 From: Nick Hynes Date: Fri, 6 Sep 2019 04:09:21 +0000 Subject: [PATCH 6/7] Add Balance type --- oasis-types/Cargo.toml | 1 + oasis-types/src/balance.rs | 142 +++++++++++++++++++++++++++++++++++++ oasis-types/src/lib.rs | 4 ++ 3 files changed, 147 insertions(+) create mode 100644 oasis-types/src/balance.rs diff --git a/oasis-types/Cargo.toml b/oasis-types/Cargo.toml index ae72f57..5da536b 100644 --- a/oasis-types/Cargo.toml +++ b/oasis-types/Cargo.toml @@ -10,6 +10,7 @@ readme = "README.md" keywords = ["blockchain", "oasis"] [dependencies] +derive_more = "0.15" hex = "0.3" serde = { version = "1.0", features = ["derive"] } diff --git a/oasis-types/src/balance.rs b/oasis-types/src/balance.rs new file mode 100644 index 0000000..69a9c83 --- /dev/null +++ b/oasis-types/src/balance.rs @@ -0,0 +1,142 @@ +#[derive( + Clone, + Copy, + Debug, + Default, + Eq, + Hash, + Ord, + PartialEq, + PartialOrd, + Display, + LowerHex, + UpperHex, + FromStr, + From, + Into, + Add, + Div, + Mul, + Rem, + Sub, + AddAssign, + DivAssign, + MulAssign, + RemAssign, + SubAssign, +)] +#[repr(C)] +pub struct Balance(pub u128); + +impl Balance { + // Alias for `mem::size_of::()`. + pub const fn size() -> usize { + std::mem::size_of::() + } +} + +impl serde::ser::Serialize for Balance { + fn serialize(&self, serializer: S) -> Result + where + S: serde::ser::Serializer, + { + serializer.serialize_bytes(&self.0.to_be_bytes()) + } +} + +impl<'de> serde::de::Deserialize<'de> for Balance { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'de>, + { + use serde::de; + + const EXPECTATION: &str = "16 bytes"; + + struct BalanceVisitor; + impl<'de> de::Visitor<'de> for BalanceVisitor { + type Value = Balance; + + fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + f.write_str(EXPECTATION) + } + + fn visit_seq(self, mut seq: V) -> Result + where + V: de::SeqAccess<'de>, + { + if let Some(len) = seq.size_hint() { + if len != Balance::size() { + return Err(de::Error::invalid_length(len, &EXPECTATION)); + } + } + + let mut bytes = [0u8; Balance::size()]; + let mut i = 0; + loop { + match seq.next_element()? { + Some(el) if i < Balance::size() => bytes[i] = el, + None if i == Balance::size() => break, + _ => return Err(de::Error::invalid_length(i, &EXPECTATION)), + } + i += 1; + } + + Ok(Balance(u128::from_be_bytes(bytes))) + } + + fn visit_bytes(self, value: &[u8]) -> Result + where + E: de::Error, + { + if value.len() == Balance::size() { + let mut bytes = [0u8; 16]; + bytes.copy_from_slice(value); + Ok(Balance(u128::from_be_bytes(bytes))) + } else { + Err(de::Error::invalid_length(value.len(), &EXPECTATION)) + } + } + } + + deserializer.deserialize_u128(BalanceVisitor) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_add() { + let mut bal = Balance::from(3); + assert_eq!(bal - Balance::from(2), Balance::from(1)); + bal += 1u128.into(); + assert_eq!(bal, Balance(4)) + } + + #[test] + fn test_mul() { + let mut bal = Balance::from(3); + bal *= 2; + assert_eq!(u128::from(bal), 6u128); + assert_eq!(bal % 4, Balance(2)); + assert_eq!(bal / 4, Balance(1)); + } + + #[test] + fn test_from_str() { + use std::str::FromStr; + assert_eq!( + Balance::from_str("21267647932558653966460912964485513216"), + Ok(Balance(21267647932558653966460912964485513216u128)) + ); + } + + #[test] + fn serde_balance() { + let orig_bal = Balance(21267647932558653966460912964485513216u128); + let bal: Balance = serde_cbor::from_slice(&serde_cbor::to_vec(&orig_bal).unwrap()).unwrap(); + assert_eq!(bal, orig_bal); + } +} diff --git a/oasis-types/src/lib.rs b/oasis-types/src/lib.rs index ef2f3a3..9db6c01 100644 --- a/oasis-types/src/lib.rs +++ b/oasis-types/src/lib.rs @@ -1,9 +1,13 @@ #[macro_use] +extern crate derive_more; +#[macro_use] extern crate serde; mod address; +mod balance; pub use address::Address; +pub use balance::Balance; #[repr(C)] #[derive(PartialEq, Eq)] From 889be5ad374578bbf530125ab82ef5731fffb169 Mon Sep 17 00:00:00 2001 From: Nick Hynes Date: Fri, 6 Sep 2019 04:19:04 +0000 Subject: [PATCH 7/7] Update tests --- oasis-build/Cargo.toml | 2 +- oasis-build/src/gen/common.rs | 1 + oasis-build/src/rpc.rs | 2 ++ oasis-rpc/Cargo.toml | 2 +- oasis-rpc/src/lib.rs | 1 + oasis-std/Cargo.toml | 2 +- oasis-std/src/lib.rs | 2 +- tests/idl-gen/res/NonDefaultFnService.json | 2 +- tests/idl-gen/res/TestService.json | 7 ++----- tests/idl-gen/src/bin/types.rs | 4 ++-- tests/idl-gen/src/lib.rs | 2 +- tests/xcc-a/res/ServiceA.json | 2 +- 12 files changed, 15 insertions(+), 14 deletions(-) diff --git a/oasis-build/Cargo.toml b/oasis-build/Cargo.toml index 198f2c9..1713a64 100644 --- a/oasis-build/Cargo.toml +++ b/oasis-build/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "oasis-build" -version = "0.2.3" +version = "0.2.4" authors = ["Oasis Labs "] edition = "2018" license = "Apache-2.0" diff --git a/oasis-build/src/gen/common.rs b/oasis-build/src/gen/common.rs index 0aa90b2..3142325 100644 --- a/oasis-build/src/gen/common.rs +++ b/oasis-build/src/gen/common.rs @@ -33,6 +33,7 @@ pub fn quote_ty(ty: &oasis_rpc::Type) -> TokenStream { Type::Bytes => quote!(Vec), Type::String => quote!(&str), Type::Address => quote!(oasis_std::Address), + Type::Balance => quote!(oasis_std::Balance), Type::Defined { namespace, ty } => { let tyq = format_ident!("{}", ty); match namespace { diff --git a/oasis-build/src/rpc.rs b/oasis-build/src/rpc.rs index ec3da04..9591ca7 100644 --- a/oasis-build/src/rpc.rs +++ b/oasis-build/src/rpc.rs @@ -213,6 +213,8 @@ macro_rules! convert_def { Type::Set(box $arg_at(0)?) } else if ty_str == "Address" { Type::Address + } else if ty_str == "Balance" { + Type::Balance } else { // this branch includes `sync`, among other things return Err(UnsupportedTypeError::NotReprC( diff --git a/oasis-rpc/Cargo.toml b/oasis-rpc/Cargo.toml index d11efe2..33f52a9 100644 --- a/oasis-rpc/Cargo.toml +++ b/oasis-rpc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "oasis-rpc" -version = "0.1.0" +version = "0.1.1" authors = ["Oasis Labs "] edition = "2018" license = "Apache-2.0" diff --git a/oasis-rpc/src/lib.rs b/oasis-rpc/src/lib.rs index 8f0af54..c18fb16 100644 --- a/oasis-rpc/src/lib.rs +++ b/oasis-rpc/src/lib.rs @@ -135,6 +135,7 @@ pub enum Type { Bytes, String, Address, + Balance, Defined { #[serde(skip_serializing_if = "Option::is_none", default)] namespace: Option, // `None` if local, otherwise refers to an entry in `Imports` diff --git a/oasis-std/Cargo.toml b/oasis-std/Cargo.toml index f538b29..47a5700 100644 --- a/oasis-std/Cargo.toml +++ b/oasis-std/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "oasis-std" -version = "0.2.3" +version = "0.2.4" license = "Apache-2.0" description = "Types and functions for developing against the Oasis platform" edition = "2018" diff --git a/oasis-std/src/lib.rs b/oasis-std/src/lib.rs index a6b22ac..c13dc91 100644 --- a/oasis-std/src/lib.rs +++ b/oasis-std/src/lib.rs @@ -20,7 +20,7 @@ pub mod reexports { } pub use oasis_macros::{default, Event, Service}; -pub use oasis_types::Address; +pub use oasis_types::{Address, Balance}; pub use crate::exe::*; diff --git a/tests/idl-gen/res/NonDefaultFnService.json b/tests/idl-gen/res/NonDefaultFnService.json index af52d3c..90dfc4b 100644 --- a/tests/idl-gen/res/NonDefaultFnService.json +++ b/tests/idl-gen/res/NonDefaultFnService.json @@ -12,5 +12,5 @@ "mutability": "immutable" } ], - "oasis_build_version": "0.2.3" + "oasis_build_version": "0.2.4" } diff --git a/tests/idl-gen/res/TestService.json b/tests/idl-gen/res/TestService.json index 1b0c8a3..ac49196 100644 --- a/tests/idl-gen/res/TestService.json +++ b/tests/idl-gen/res/TestService.json @@ -91,10 +91,7 @@ "type": "address" }, { - "type": "u64" - }, - { - "type": "address" + "type": "balance" } ] } @@ -278,5 +275,5 @@ } } ], - "oasis_build_version": "0.2.3" + "oasis_build_version": "0.2.4" } diff --git a/tests/idl-gen/src/bin/types.rs b/tests/idl-gen/src/bin/types.rs index 136ecf2..abbff90 100644 --- a/tests/idl-gen/src/bin/types.rs +++ b/tests/idl-gen/src/bin/types.rs @@ -5,8 +5,8 @@ extern crate serde; use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; -use oasis_std::{Address, Context, Event, Service}; use map_vec::{Map, Set}; +use oasis_std::{Address, Balance, Context, Event, Service}; #[derive(Serialize, Deserialize, Debug, Clone)] pub enum InnerTy { @@ -14,7 +14,7 @@ pub enum InnerTy { Field2, } -pub type Tuple = (Address, u64, Address); +pub type Tuple = (Address, Balance); #[derive(Serialize, Deserialize, Event, Default)] pub struct TestEvent { diff --git a/tests/idl-gen/src/lib.rs b/tests/idl-gen/src/lib.rs index d5c1825..dd2640f 100644 --- a/tests/idl-gen/src/lib.rs +++ b/tests/idl-gen/src/lib.rs @@ -1,5 +1,5 @@ pub fn test_oasis_interface(bin_name: &str, service_name: &str) { - let mf_dir = std::path::PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap());; + let mf_dir = std::path::PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap()); let wasm_path = mf_dir.join(format!("../target/wasm32-wasi/debug/{}.wasm", bin_name)); let iface_bytes = walrus::Module::from_file(wasm_path) diff --git a/tests/xcc-a/res/ServiceA.json b/tests/xcc-a/res/ServiceA.json index 10c3277..526a966 100644 --- a/tests/xcc-a/res/ServiceA.json +++ b/tests/xcc-a/res/ServiceA.json @@ -45,5 +45,5 @@ } } ], - "oasis_build_version": "0.2.3" + "oasis_build_version": "0.2.4" }