diff --git a/.gitmodules b/.gitmodules
index 4997c847f695a0b3f4ebbe1ab461b7d7d6cebf67..daa6a58c2dcf4d848f0fbaff68636c7186e5e237 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -9,3 +9,11 @@
[submodule "programs/snapshot"]
path = programs/snapshot
url = https://github.com/EOSIO/genesis.git
+[submodule "contracts/musl/upstream"]
+ path = contracts/musl/upstream
+ url = https://github.com/EOSIO/musl.git
+ branch = eosio
+[submodule "contracts/libc++/upstream"]
+ path = contracts/libc++/upstream
+ url = https://github.com/EOSIO/libcxx.git
+ branch = eosio
diff --git a/.travis.yml b/.travis.yml
index 190bd8bbd4daf8db90da47a5239a3de8e71ae19b..23952ef80062a4490e7984f44bd09000fbecccb6 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -78,7 +78,7 @@ script:
- mkdir build && cd build
- ${CMAKE_DIR}cmake -G Ninja -DWASM_LLVM_CONFIG=$TRAVIS_BUILD_DIR/ext/wasm-compiler/bin/llvm-config -DSecp256k1_ROOT_DIR=$TRAVIS_BUILD_DIR/ext -DBINARYEN_ROOT=$TRAVIS_BUILD_DIR/ext/wasm-compiler -DCMAKE_PREFIX_PATH=$TRAVIS_BUILD_DIR/ext -DCMAKE_BUILD_TYPE=Release -DBUILD_MONGO_DB_PLUGIN=true $EOS_CMAKE_OPTIONS ..
- ninja -j4
- - '[ "$TRAVIS_OS_NAME" == "osx" ] || ctest --output-on-failure'
+ - '[ "$TRAVIS_OS_NAME" == "osx" ] || (export EOSLIB=$TRAVIS_BUILD_DIR/contracts; ctest --output-on-failure)'
- cpack
deploy:
diff --git a/CMakeModules/wasm.cmake b/CMakeModules/wasm.cmake
index 390dcbd9b52d176985ce4389ad7fad8c5f7a603e..97e782f7c078f616199528ac31dc6e87d935d260 100644
--- a/CMakeModules/wasm.cmake
+++ b/CMakeModules/wasm.cmake
@@ -58,15 +58,22 @@ if( NOT ("${WASM_CLANG}" STREQUAL "" OR "${WASM_LLC}" STREQUAL "" OR "${WASM_LLV
set(WASM_TOOLCHAIN TRUE)
endif()
-macro(add_wast_target target INCLUDE_FOLDERS DESTINATION_FOLDER)
+macro(compile_wast)
+ cmake_parse_arguments(ARG "" "TARGET" "SOURCE_FILES;INCLUDE_FOLDERS" ${ARGN})
+ set(target ${ARG_TARGET})
# NOTE: Setting SOURCE_FILE and looping over it to avoid cmake issue with compilation ${target}.bc's rule colliding with
- # linking ${target}.bc's rule
- set(SOURCE_FILE ${target}.cpp)
+ # linking ${target}.bc's rule
+ if ("${ARG_SOURCE_FILES}" STREQUAL "")
+ set(SOURCE_FILES ${target}.cpp)
+ else()
+ set(SOURCE_FILES ${ARG_SOURCE_FILES})
+ endif()
set(outfiles "")
- foreach(srcfile ${SOURCE_FILE})
+ foreach(srcfile ${SOURCE_FILES})
get_filename_component(outfile ${srcfile} NAME)
+ get_filename_component(extension ${srcfile} EXT)
get_filename_component(infile ${srcfile} ABSOLUTE)
# -ffreestanding
@@ -89,12 +96,17 @@ macro(add_wast_target target INCLUDE_FOLDERS DESTINATION_FOLDER)
# -fno-exceptions
# Disable the generation of extra code needed to propagate exceptions
+ if ("${extension}" STREQUAL ".c")
+ set(STDFLAG -D_XOPEN_SOURCE=700)
+ else()
+ set(STDFLAG "--std=c++14")
+ endif()
- set(WASM_COMMAND ${WASM_CLANG} -emit-llvm -O3 --std=c++14 --target=wasm32 -ffreestanding
- -nostdlib -fno-threadsafe-statics -fno-rtti -fno-exceptions
+ set(WASM_COMMAND ${WASM_CLANG} -emit-llvm -O3 ${STDFLAG} --target=wasm32 -ffreestanding
+ -nostdlib -nostdlibinc -fno-threadsafe-statics -fno-rtti -fno-exceptions
-c ${infile} -o ${outfile}.bc
)
- foreach(folder ${INCLUDE_FOLDERS})
+ foreach(folder ${ARG_INCLUDE_FOLDERS})
list(APPEND WASM_COMMAND -I ${folder})
endforeach()
@@ -111,18 +123,51 @@ macro(add_wast_target target INCLUDE_FOLDERS DESTINATION_FOLDER)
endforeach(srcfile)
- add_custom_command(OUTPUT ${target}.bc
+ set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${target}.bc)
+
+endmacro(compile_wast)
+
+macro(add_wast_library)
+ cmake_parse_arguments(ARG "" "TARGET;DESTINATION_FOLDER" "SOURCE_FILES;INCLUDE_FOLDERS" ${ARGN})
+ set(target ${ARG_TARGET})
+ compile_wast(TARGET ${ARG_TARGET} SOURCE_FILES ${ARG_SOURCE_FILES} INCLUDE_FOLDERS ${ARG_INCLUDE_FOLDERS})
+
+ get_filename_component("${ARG_TARGET}_BC_FILENAME" "${ARG_DESTINATION_FOLDER}/${ARG_TARGET}.bc" ABSOLUTE CACHE)
+ add_custom_target(${target} ALL DEPENDS ${${ARG_TARGET}_BC_FILENAME})
+
+ add_custom_command(OUTPUT ${${ARG_TARGET}_BC_FILENAME}
DEPENDS ${outfiles}
- COMMAND ${WASM_LLVM_LINK} -o ${target}.bc ${outfiles}
- COMMENT "Linking LLVM bitcode ${target}.bc"
+ COMMAND ${WASM_LLVM_LINK} -o ${${ARG_TARGET}_BC_FILENAME} ${outfiles}
+ COMMENT "Linking LLVM bitcode library ${target}.bc"
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ VERBATIM
+ )
+
+endmacro(add_wast_library)
+
+macro(add_wast_executable)
+ cmake_parse_arguments(ARG "" "TARGET;DESTINATION_FOLDER" "SOURCE_FILES;INCLUDE_FOLDERS;LIBRARIES" ${ARGN})
+ set(target ${ARG_TARGET})
+ set(DESTINATION_FOLDER ${ARG_DESTINATION_FOLDER})
+
+ compile_wast(TARGET ${ARG_TARGET} SOURCE_FILES ${ARG_SOURCE_FILES} INCLUDE_FOLDERS ${ARG_INCLUDE_FOLDERS})
+
+ foreach(lib ${ARG_LIBRARIES})
+ list(APPEND LIBRARIES ${${lib}_BC_FILENAME})
+ endforeach()
+ add_custom_command(OUTPUT ${target}.bc
+ DEPENDS ${outfiles} ${ARG_LIBRARIES} ${LIBRARIES}
+ COMMAND ${WASM_LLVM_LINK} -only-needed -o ${target}.bc ${outfiles} ${LIBRARIES}
+ COMMENT "Linking LLVM bitcode executable ${target}.bc"
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
VERBATIM
)
+
set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${target}.bc)
add_custom_command(OUTPUT ${target}.s
DEPENDS ${target}.bc
- COMMAND ${WASM_LLC} -asm-verbose=false -o ${target}.s ${target}.bc
+ COMMAND ${WASM_LLC} -thread-model=single -asm-verbose=false -o ${target}.s ${target}.bc
COMMENT "Generating textual assembly ${target}.s"
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
VERBATIM
@@ -132,7 +177,6 @@ macro(add_wast_target target INCLUDE_FOLDERS DESTINATION_FOLDER)
add_custom_command(OUTPUT ${DESTINATION_FOLDER}/${target}.wast
DEPENDS ${target}.s
COMMAND ${BINARYEN_BIN}/s2wasm -o ${DESTINATION_FOLDER}/${target}.wast -s 4096 ${target}.s
-
COMMENT "Generating WAST ${target}.wast"
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
VERBATIM
@@ -149,7 +193,7 @@ macro(add_wast_target target INCLUDE_FOLDERS DESTINATION_FOLDER)
VERBATIM
)
- if (EXISTS ${DESTINATION_FOLDER}/${target}.abi )
+ if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${target}.abi )
add_custom_command(OUTPUT ${DESTINATION_FOLDER}/${target}.abi.hpp
DEPENDS ${DESTINATION_FOLDER}/${target}.abi
COMMAND echo "const char* const ${TARGET_VARIABLE}_abi = R\"=====(" > ${DESTINATION_FOLDER}/${target}.abi.hpp
@@ -163,13 +207,12 @@ macro(add_wast_target target INCLUDE_FOLDERS DESTINATION_FOLDER)
else()
endif()
-
add_custom_target(${target} ALL DEPENDS ${DESTINATION_FOLDER}/${target}.wast.hpp ${extra_target_dependency})
set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${DESTINATION_FOLDER}/${target}.wast.hpp)
- set_property(TARGET ${target} PROPERTY INCLUDE_DIRECTORIES ${INCLUDE_FOLDERS})
+ set_property(TARGET ${target} PROPERTY INCLUDE_DIRECTORIES ${ARG_INCLUDE_FOLDERS})
set(extra_target_dependency)
-endmacro(add_wast_target)
+endmacro(add_wast_executable)
diff --git a/README.md b/README.md
index 4e18d5c18bdc964569018d77954d40c4a2de255b..857141851d670977f6c6643aea9b9ceb22a6228a 100644
--- a/README.md
+++ b/README.md
@@ -26,6 +26,7 @@ EOS.IO currently supports the following operating systems:
5. [Developer Telegram Group](https://t.me/joinchat/EaEnSUPktgfoI-XPfMYtcQ)
6. [White Paper](https://github.com/EOSIO/Documentation/blob/master/TechnicalWhitePaper.md)
7. [Roadmap](https://github.com/EOSIO/Documentation/blob/master/Roadmap.md)
+8. [Wiki](https://github.com/EOSIO/eos/wiki)
# Table of contents
@@ -40,6 +41,7 @@ EOS.IO currently supports the following operating systems:
1. [Getting the code](#getcode)
2. [Building from source code](#build)
3. [Creating and launching a single-node testnet](#singlenode)
+ 4. [Next steps](#nextsteps)
4. [Example Currency Contract Walkthrough](#smartcontracts)
1. [Example Contracts](#smartcontractexample)
2. [Setting up a wallet and importing account key](#walletimport)
@@ -77,7 +79,7 @@ We are working on supporting Centos, Amazon Linux & Red Hat in future releases.
It is called eosio_build.sh
```bash
-cd ~/eos
+cd eos
./eosio_build.sh
```
Choose whether you will be building for a local testnet or for the public testnet and jump to the appropriate section below. Clone the EOS repository recursively as described and run eosio_build.sh located in the root `eos` folder.
@@ -87,7 +89,7 @@ Choose whether you will be building for a local testnet or for the public testne
We strongly recommend following the instructions for building the public testnet version for [Ubuntu](#autoubuntupublic) or [Mac OS X](#automacpublic). `master` is in pieces on the garage floor while we rebuild this hotrod. This notice will be removed when `master` is usable again. Your patience is appreciated.
-#### Clean install Linux (Ubuntu & Fedora) for a local testnet
+#### :no_entry: Clean install Linux (Ubuntu & Fedora) for a local testnet :no_entry:
```bash
git clone https://github.com/eosio/eos --recursive
@@ -96,6 +98,12 @@ cd eos
./eosio_build.sh
```
+For ease of contract development, one further step is required:
+
+```bash
+sudo make install
+```
+
Now you can proceed to the next step - [Creating and launching a single-node testnet](#singlenode)
@@ -105,14 +113,21 @@ Now you can proceed to the next step - [Creating and launching a single-node tes
git clone https://github.com/eosio/eos --recursive
cd eos
-git checkout dawn-2.x
+
+git checkout DAWN-2018-01-25
./eosio_build.sh
```
+For ease of contract development, one further step is required:
+
+```bash
+sudo make install
+```
+
Now you can proceed to the next step - [Running a node on the public testnet](#publictestnet)
-#### MacOS for a local testnet
+#### :no_entry: MacOS for a local testnet :no_entry:
Before running the script make sure you have installed/updated XCode. Note: The build script
will install homebrew if it is not already installed on you system. [Homebrew Website](https://brew.sh)
@@ -126,6 +141,12 @@ cd eos
./eosio_build.sh
```
+For ease of contract development, one further step is required:
+
+```bash
+make install
+```
+
Now you can proceed to the next step - [Creating and launching a single-node testnet](#singlenode)
@@ -140,10 +161,17 @@ Then clone the EOS repository recursively, checkout the branch that is compatibl
git clone https://github.com/eosio/eos --recursive
cd eos
-git checkout dawn-2.x
+
+git checkout DAWN-2018-01-25
./eosio_build.sh
```
+For ease of contract development, one further step is required:
+
+```bash
+make install
+```
+
Now you can proceed to the next step - [Running a node on the public testnet](#publictestnet)
@@ -247,6 +275,10 @@ When running `eosiod` you should get log messages similar to below. It means the
1578001ms thread-0 producer_plugin.cpp:207 block_production_loo ] initc generated block #2 @ 2017-09-04T04:26:18 with 0 trxs 0 pending
...
```
+
+### Next Steps
+
+Further documentation is available in the [wiki](https://github.com/EOSIO/eos/wiki). Wiki pages include detailed reference documentation for all programs and tools and the database schema and API. The wiki also includes a section describing smart contract development. A simple walkthrough of the "currency" contract follows.
## Example "Currency" Contract Walkthrough
@@ -529,7 +561,7 @@ Dependencies:
* Clang 4.0.0
* CMake 3.5.1
-* Boost 1.64
+* Boost 1.66
* OpenSSL
* LLVM 4.0
* [secp256k1-zkp (Cryptonomex branch)](https://github.com/cryptonomex/secp256k1-zkp.git)
@@ -550,14 +582,14 @@ sudo apt-get install clang-4.0 lldb-4.0 libclang-4.0-dev cmake make \
autoconf libtool git
```
-Install Boost 1.64:
+Install Boost 1.66:
```bash
cd ~
-wget -c 'https://sourceforge.net/projects/boost/files/boost/1.64.0/boost_1_64_0.tar.bz2/download' -O boost_1.64.0.tar.bz2
-tar xjf boost_1.64.0.tar.bz2
-cd boost_1_64_0/
-echo "export BOOST_ROOT=$HOME/boost_1_64_0" >> ~/.bash_profile
+wget -c 'https://sourceforge.net/projects/boost/files/boost/1.64.0/boost_1_66_0.tar.bz2/download' -O boost_1.64.0.tar.bz2
+tar xjf boost_1.66.0.tar.bz2
+cd boost_1_66_0/
+echo "export BOOST_ROOT=$HOME/boost_1_66_0" >> ~/.bash_profile
source ~/.bash_profile
./bootstrap.sh "--prefix=$BOOST_ROOT"
./b2 install
@@ -687,14 +719,14 @@ cd ..
mkdir build
cd build
cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX=.. -DLLVM_TARGETS_TO_BUILD= -DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=WebAssembly -DCMAKE_BUILD_TYPE=Release ../
-make -j4 install
+make -j$( nproc ) install
```
Add `WASM_LLVM_CONFIG` and `LLVM_DIR` to your `.bash_profile`:
```bash
echo "export WASM_LLVM_CONFIG=~/wasm-compiler/llvm/bin/llvm-config" >> ~/.bash_profile
-echo "export LLVM_DIR=/usr/local/Cellar/llvm/4.0.1/lib/cmake/llvm" >> ~/.bash_profile
+echo "export LLVM_DIR=/usr/local/Cellar/llvm@4/4.0.1/lib/cmake/llvm/" >> ~/.bash_profile
source ~/.bash_profile
```
@@ -718,7 +750,7 @@ Install Boost 1.66:
cd ~
curl -L https://dl.bintray.com/boostorg/release/1.66.0/source/boost_1_66_0.tar.bz2 > boost_1.66.0.tar.bz2
tar xf boost_1.66.0.tar.bz2
-echo "export BOOST_ROOT=$HOME/boost_1_64_0" >> ~/.bash_profile
+echo "export BOOST_ROOT=$HOME/boost_1_66_0" >> ~/.bash_profile
source ~/.bash_profile
cd boost_1_66_0/
./bootstrap.sh "--prefix=$BOOST_ROOT"
@@ -774,7 +806,7 @@ Add `WASM_LLVM_CONFIG` and `LLVM_DIR` to your `.bash_profile`:
```bash
echo "export WASM_LLVM_CONFIG=~/wasm-compiler/llvm/bin/llvm-config" >> ~/.bash_profile
-echo "export LLVM_DIR=/usr/local/Cellar/llvm/4.0.1/lib/cmake/llvm" >> ~/.bash_profile
+echo "export LLVM_DIR=~/wasm-compiler/lib/cmake/llvm" >> ~/.bash_profile
source ~/.bash_profile
```
Your environment is set up. Now you can build EOS and run a node.
diff --git a/contracts/CMakeLists.txt b/contracts/CMakeLists.txt
index 1fcbee2b0c95a2795b0ef2ac557d5e852271cacc..c3a270d1a4a0598002693f9e285ea6ad64106f7e 100644
--- a/contracts/CMakeLists.txt
+++ b/contracts/CMakeLists.txt
@@ -1,16 +1,24 @@
+set(STANDARD_INCLUDE_FOLDERS ${CMAKE_SOURCE_DIR}/contracts ${CMAKE_SOURCE_DIR}/contracts/libc++/upstream/include ${CMAKE_SOURCE_DIR}/contracts/musl/upstream/include)
+
+add_subdirectory(eosiolib)
+add_subdirectory(musl)
+add_subdirectory(libc++)
+
add_subdirectory(eosio.system)
add_subdirectory(identity)
add_subdirectory(currency)
+add_subdirectory(stltest)
#add_subdirectory(bancor)
#add_subdirectory(eosio.system)
add_subdirectory(asserter)
#add_subdirectory(exchange)
-#add_subdirectory(infinite)
+add_subdirectory(infinite)
add_subdirectory(proxy)
add_subdirectory(test_api)
#add_subdirectory(simpledb)
#add_subdirectory(storage)
#add_subdirectory(social)
+add_subdirectory(test.system)
add_subdirectory(noop)
install( DIRECTORY eosiolib DESTINATION include/ )
diff --git a/contracts/asserter/CMakeLists.txt b/contracts/asserter/CMakeLists.txt
index f55150ec7e1b7b1c2352c3daccaee6ca3986c28c..e0b3445bf3f533b1f80e5d07a9421b3ebe883510 100644
--- a/contracts/asserter/CMakeLists.txt
+++ b/contracts/asserter/CMakeLists.txt
@@ -1,3 +1,8 @@
file(GLOB ABI_FILES "*.abi")
configure_file("${ABI_FILES}" "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY)
-add_wast_target(asserter "${CMAKE_SOURCE_DIR}/contracts" ${CMAKE_CURRENT_BINARY_DIR})
+
+add_wast_executable(TARGET asserter
+ INCLUDE_FOLDERS "${STANDARD_INCLUDE_FOLDERS}"
+ LIBRARIES eosiolib
+ DESTINATION_FOLDER ${CMAKE_CURRENT_BINARY_DIR}
+)
diff --git a/contracts/asserter/asserter.cpp b/contracts/asserter/asserter.cpp
index a20e6a20b3d8efb6e5b927c4220dbea996904205..32604bbdcdb123e4f8321cad5f63d59791504fdc 100644
--- a/contracts/asserter/asserter.cpp
+++ b/contracts/asserter/asserter.cpp
@@ -29,9 +29,9 @@ extern "C" {
}
// maybe assert?
- assert(def->condition, def->message);
+ eos_assert(def->condition, def->message);
} else if( action == N(provereset) ) {
- assert(global_variable == 45, "Global Variable Initialized poorly");
+ eos_assert(global_variable == 45, "Global Variable Initialized poorly");
global_variable = 100;
}
}
diff --git a/contracts/bancor/CMakeLists.txt b/contracts/bancor/CMakeLists.txt
index c398123e77dca4c75148c414a1107af94bf94abe..0c9c0f17e21245a8590d41733f0caf79b5571c08 100644
--- a/contracts/bancor/CMakeLists.txt
+++ b/contracts/bancor/CMakeLists.txt
@@ -1,3 +1,8 @@
file(GLOB ABI_FILES "*.abi")
configure_file("${ABI_FILES}" "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY)
-add_wast_target(bancor "${CMAKE_SOURCE_DIR}/contracts" ${CMAKE_CURRENT_BINARY_DIR})
+
+add_wast_executable(TARGET bancor
+ INCLUDE_FOLDERS "${STANDARD_INCLUDE_FOLDERS}"
+ LIBRARIES eosiolib
+ DESTINATION_FOLDER ${CMAKE_CURRENT_BINARY_DIR}
+)
diff --git a/contracts/bancor/converter.hpp b/contracts/bancor/converter.hpp
index 2becf4e651884fec06f79d43d40a2e2575d8e39b..682a8e12053741c1ae455f1f14cf2ffe03c0d4d0 100644
--- a/contracts/bancor/converter.hpp
+++ b/contracts/bancor/converter.hpp
@@ -82,7 +82,7 @@ namespace bancor {
save_and_send( trans.from, state, output, args.min_return );
}
else {
- assert( false, "invalid to currency" );
+ eos_assert( false, "invalid to currency" );
}
}
@@ -118,7 +118,7 @@ namespace bancor {
template
static void start_convert( const typename CurrencyType::transfer_memo& trans ) {
auto args = unpack( trans.memo );
- assert( args.to_currency_type != trans.quantity.token_type(), "cannot convert to self" );
+ eos_assert( args.to_currency_type != trans.quantity.token_type(), "cannot convert to self" );
auto state = read_converter_state();
on_convert( trans, args, state );
@@ -148,7 +148,7 @@ namespace bancor {
if( trans.to == converter_account ) {
start_convert( trans );
} else {
- assert( trans.from == converter_account,
+ eos_assert( trans.from == converter_account,
"received unexpected notification of transfer" );
}
}
@@ -159,7 +159,7 @@ namespace bancor {
converter_currency::issue,
first_currency::transfer,
second_currency::transfer ) {
- assert( false, "received unexpected action" );
+ eos_assert( false, "received unexpected action" );
}
}
}; /// converter_contract
diff --git a/contracts/currency/CMakeLists.txt b/contracts/currency/CMakeLists.txt
index 35a52d86b417a15072de33c417ffaa67b35672f9..f848c001f8f57661936b1ecdef38f8d2472a1c72 100644
--- a/contracts/currency/CMakeLists.txt
+++ b/contracts/currency/CMakeLists.txt
@@ -1,3 +1,8 @@
file(GLOB ABI_FILES "*.abi")
configure_file("${ABI_FILES}" "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY)
-add_wast_target(currency "${CMAKE_SOURCE_DIR}/contracts" ${CMAKE_CURRENT_BINARY_DIR})
+
+add_wast_executable(TARGET currency
+ INCLUDE_FOLDERS "${STANDARD_INCLUDE_FOLDERS}"
+ LIBRARIES eosiolib
+ DESTINATION_FOLDER ${CMAKE_CURRENT_BINARY_DIR}
+)
diff --git a/contracts/dice/dice.cpp b/contracts/dice/dice.cpp
index 55cf3cd8bdcde35e9189ef4d76699983dfcb44a4..05d9bee11c62588471a4e4285c93df9f3cc8bf26 100644
--- a/contracts/dice/dice.cpp
+++ b/contracts/dice/dice.cpp
@@ -6,8 +6,8 @@
namespace dice {
void apply_offer( const offer_bet& offer ) {
- assert( offer.amount > 0, "insufficient bet" );
- assert( !hasOffer( offer.commitment ), "offer with this commitment already exist" );
+ eos_assert( offer.amount > 0, "insufficient bet" );
+ eos_assert( !hasOffer( offer.commitment ), "offer with this commitment already exist" );
require_auth( offer.player );
auto acnt = get_account( offer.player );
diff --git a/contracts/eosio.system/CMakeLists.txt b/contracts/eosio.system/CMakeLists.txt
index 22ecb1546ce5209bafd39449bf9096e3ce99f6ef..1bfb4683f09fb3edd1f6f46b0591075662f5c544 100644
--- a/contracts/eosio.system/CMakeLists.txt
+++ b/contracts/eosio.system/CMakeLists.txt
@@ -1,3 +1,8 @@
file(GLOB ABI_FILES "*.abi")
configure_file("${ABI_FILES}" "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY)
-add_wast_target(eosio.system "${CMAKE_SOURCE_DIR}/contracts" ${CMAKE_CURRENT_BINARY_DIR})
+
+add_wast_executable(TARGET eosio.system
+ INCLUDE_FOLDERS "${STANDARD_INCLUDE_FOLDERS}"
+ LIBRARIES eosiolib
+ DESTINATION_FOLDER ${CMAKE_CURRENT_BINARY_DIR}
+)
diff --git a/contracts/eosio.system/eosio.system.abi b/contracts/eosio.system/eosio.system.abi
index b67e3c8c6149b00d3b558ffb28b17e1881998617..8ae709721b81b7117288bfded329239b6c1e80a4 100644
--- a/contracts/eosio.system/eosio.system.abi
+++ b/contracts/eosio.system/eosio.system.abi
@@ -1,9 +1,5 @@
{
- "types": [{
- "new_type_name": "account_name",
- "type": "name"
- }
- ],
+ "types": [],
"structs": [{
"name": "transfer",
"base": "",
diff --git a/contracts/eosio.system/eosio.system.cpp b/contracts/eosio.system/eosio.system.cpp
index d228a833e50bb09ed5d2c580db83b3d359a40e84..ee50cc7ea602da6b277487e0600910de94a8b64d 100644
--- a/contracts/eosio.system/eosio.system.cpp
+++ b/contracts/eosio.system/eosio.system.cpp
@@ -11,6 +11,6 @@ extern "C" {
/// The apply method implements the dispatch of events to this contract
void apply( uint64_t code, uint64_t act ) {
- eosiosystem::contract::apply( code, act );
+ eosiosystem::contract::apply( code, act );
}
}
diff --git a/contracts/eosio.system/eosio.system.hpp b/contracts/eosio.system/eosio.system.hpp
index 6b2c9dff14ce585a4a3f71dc7e04dd41eb69c79e..8bcb2a62c0993da49d6ca0349fa9083f576c9cbb 100644
--- a/contracts/eosio.system/eosio.system.hpp
+++ b/contracts/eosio.system/eosio.system.hpp
@@ -17,7 +17,7 @@ namespace eosiosystem {
template
class contract {
public:
- static const account_name system_account = N(eosio.system);
+ static const account_name system_account = SystemAccount;
typedef eosio::generic_currency< eosio::token > currency;
struct total_bandwidth {
@@ -103,8 +103,8 @@ namespace eosiosystem {
static void apply( account_name code, action_name act ) {
if( !eosio::dispatch( code, act) ) {
if ( !eosio::dispatch( code, act ) ) {
- eosio::print("Unexpected action: ", act, "\n");
- assert( false, "received unexpected action");
+ eosio::print("Unexpected action: ", eosio::name(act), "\n");
+ eos_assert( false, "received unexpected action");
}
}
} /// apply
diff --git a/contracts/eosiolib/CMakeLists.txt b/contracts/eosiolib/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..0743b39d61d788ba7cf45de0496042002f2bd5c4
--- /dev/null
+++ b/contracts/eosiolib/CMakeLists.txt
@@ -0,0 +1,5 @@
+add_wast_library(TARGET eosiolib
+ INCLUDE_FOLDERS "${STANDARD_INCLUDE_FOLDERS}"
+ DESTINATION_FOLDER ${CMAKE_CURRENT_BINARY_DIR}
+)
+
diff --git a/contracts/eosiolib/action.h b/contracts/eosiolib/action.h
index 3262ae6f60aef0e9dfe85f3c36e79519deeb342f..14fc6d9c3102d11890191637122677cf6fefec29 100644
--- a/contracts/eosiolib/action.h
+++ b/contracts/eosiolib/action.h
@@ -61,8 +61,8 @@ extern "C" {
* account_name code = current_receiver();
* print(Name(code)); // Output: eos
*
- * assert(Name(current_receiver()) === "eos", "This action expects to be received by eos"); // Do nothing
- * assert(Name(current_receiver()) === "inita", "This action expects to be received by inita"); // Throws exception and roll back transfer transaction
+ * eos_assert(Name(current_receiver()) === "eos", "This action expects to be received by eos"); // Do nothing
+ * eos_assert(Name(current_receiver()) === "inita", "This action expects to be received by inita"); // Throws exception and roll back transfer transaction
*
* print(now()); // Output: timestamp of last accepted block
*
diff --git a/contracts/eosiolib/action.hpp b/contracts/eosiolib/action.hpp
index 994827162a6dd4dfff9f6d597f2d05bdf689a9d8..1e56ea6d599e734c724f2e6620ccf4c80f0f6fd8 100644
--- a/contracts/eosiolib/action.hpp
+++ b/contracts/eosiolib/action.hpp
@@ -40,7 +40,7 @@ namespace eosio {
T current_action() {
T value;
auto read = read_action( &value, sizeof(value) );
- assert( read >= sizeof(value), "action shorter than expected" );
+ eos_assert( read >= sizeof(value), "action shorter than expected" );
return value;
}
diff --git a/contracts/eosiolib/contracts.dox b/contracts/eosiolib/contracts.dox
index af276294a96aa3e8dc2d3d0ea01fdd51aabe743c..076b9b15b0dce781a83aa87ae7f7a2e1adb5c1ba 100644
--- a/contracts/eosiolib/contracts.dox
+++ b/contracts/eosiolib/contracts.dox
@@ -51,7 +51,7 @@
if( action == N(transfer) )
currency::apply_currency_transfer( current_action< currency::transfer >() );
} else {
- assert( false, "rejecting unexpected event" );
+ eos_assert( false, "rejecting unexpected event" );
}
}
}
diff --git a/contracts/eosiolib/crypto.h b/contracts/eosiolib/crypto.h
index afad9850001b6f0a4da4690f97f5a445874dfa8e..7f7e50104d8ef4b1a23304ef6391a1abce24dfda 100644
--- a/contracts/eosiolib/crypto.h
+++ b/contracts/eosiolib/crypto.h
@@ -10,14 +10,14 @@ extern "C" {
*
* checksum calc_hash;
* sha256( data, length, &calc_hash );
- * assert( calc_hash == hash, "invalid hash" );
+ * eos_assert( calc_hash == hash, "invalid hash" );
*
* This method is optimized to a NO-OP when in fast evaluation mode
*/
-void assert_sha256( char* data, uint32_t length, const checksum* hash );
+void eos_assert_sha256( char* data, uint32_t length, const checksum* hash );
/**
* Calculates sha256( data,length) and stores result in memory pointed to by hash
*/
void sha256( char* data, uint32_t length, checksum* hash );
-}
\ No newline at end of file
+}
diff --git a/contracts/eosiolib/datastream.hpp b/contracts/eosiolib/datastream.hpp
index d298b21ff5e1d2d5b0cf908850728b2840bb95fe..0b5b848e7f62723855a599cb3052ee5f4cfd7e32 100644
--- a/contracts/eosiolib/datastream.hpp
+++ b/contracts/eosiolib/datastream.hpp
@@ -33,7 +33,7 @@ class datastream {
* @param s the number of bytes to read
*/
inline bool read( char* d, size_t s ) {
- assert( size_t(_end - _pos) >= (size_t)s, "read" );
+ eos_assert( size_t(_end - _pos) >= (size_t)s, "read" );
memcpy( d, _pos, s );
_pos += s;
return true;
@@ -46,7 +46,7 @@ class datastream {
* @param s The number of bytes to write
*/
inline bool write( const char* d, size_t s ) {
- assert( _end - _pos >= (int32_t)s, "write" );
+ eos_assert( _end - _pos >= (int32_t)s, "write" );
memcpy( _pos, d, s );
_pos += s;
return true;
@@ -58,7 +58,7 @@ class datastream {
* @param c byte to write
*/
inline bool put(char c) {
- assert( _pos < _end, "put" );
+ eos_assert( _pos < _end, "put" );
*_pos = c;
++_pos;
return true;
@@ -72,7 +72,7 @@ class datastream {
inline bool get( unsigned char& c ) { return get( *(char*)&c ); }
inline bool get( char& c )
{
- assert( _pos < _end, "get" );
+ eos_assert( _pos < _end, "get" );
c = *_pos;
++_pos;
return true;
@@ -428,5 +428,3 @@ bytes pack( const T& value ) {
}
-
-
diff --git a/contracts/eosiolib/db.hpp b/contracts/eosiolib/db.hpp
index 8fe7f3996903dc97f0a8a42a6511c22d89dcf154..1c71e6d65def2d7f72f1083f0da09ee15c2706fe 100644
--- a/contracts/eosiolib/db.hpp
+++ b/contracts/eosiolib/db.hpp
@@ -388,7 +388,7 @@ struct table {
* @return true if successful store.
*/
static bool store( const Record& r, uint64_t s = scope, uint64_t b = bta ) {
- assert( impl::store( s, table_n, b, &r, sizeof(r) ), "error storing record" );
+ eos_assert( impl::store( s, table_n, b, &r, sizeof(r) ), "error storing record" );
return true;
}
@@ -401,7 +401,7 @@ struct table {
* @return true if successful update.
*/
static bool update( const Record& r, uint64_t s = scope, uint64_t b = bta ) {
- assert( impl::update( s, table_n, b, &r, sizeof(r) ), "error updating record" );
+ eos_assert( impl::update( s, table_n, b, &r, sizeof(r) ), "error updating record" );
return true;
}
diff --git a/contracts/eosiolib/eosiolib.cpp b/contracts/eosiolib/eosiolib.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..fb577d057d048835bb16116d9787bbcd5e3cc0a1
--- /dev/null
+++ b/contracts/eosiolib/eosiolib.cpp
@@ -0,0 +1,505 @@
+#include "memory.hpp"
+
+namespace eosio {
+
+ using ::memset;
+ using ::memcpy;
+
+ /**
+ * @defgroup memorycppapi Memory C++ API
+ * @brief Defines common memory functions
+ * @ingroup memoryapi
+ *
+ * @{
+ */
+
+ class memory_manager // NOTE: Should never allocate another instance of memory_manager
+ {
+ friend void* ::malloc(size_t size);
+ friend void* ::calloc(size_t count, size_t size);
+ friend void* ::realloc(void* ptr, size_t size);
+ friend void ::free(void* ptr);
+ public:
+ memory_manager()
+ // NOTE: it appears that WASM has an issue with initialization lists if the object is globally allocated,
+ // and seems to just initialize members to 0
+ : _heaps_actual_size(0)
+ , _active_heap(0)
+ , _active_free_heap(0)
+ {
+ }
+
+ private:
+ class memory;
+
+ memory* next_active_heap()
+ {
+ memory* const current_memory = _available_heaps + _active_heap;
+
+ // make sure we will not exceed the 1M limit (needs to match wasm_interface.cpp _max_memory)
+ auto remaining = 1024 * 1024 - reinterpret_cast(sbrk(0));
+ if (remaining <= 0)
+ {
+ // ensure that any remaining unallocated memory gets cleaned up
+ current_memory->cleanup_remaining();
+ ++_active_heap;
+ _heaps_actual_size = _active_heap;
+ return nullptr;
+ }
+
+ const uint32_t new_heap_size = remaining > _new_heap_size ? _new_heap_size : remaining;
+ char* new_memory_start = static_cast(sbrk(new_heap_size));
+ // if we can expand the current memory, keep working with it
+ if (current_memory->expand_memory(new_memory_start, new_heap_size))
+ return current_memory;
+
+ // ensure that any remaining unallocated memory gets cleaned up
+ current_memory->cleanup_remaining();
+
+ ++_active_heap;
+ memory* const next = _available_heaps + _active_heap;
+ next->init(new_memory_start, new_heap_size);
+
+ return next;
+ }
+
+ void* malloc(uint32_t size)
+ {
+ if (size == 0)
+ return nullptr;
+
+ // see Note on ctor
+ if (_heaps_actual_size == 0)
+ _heaps_actual_size = _heaps_size;
+
+ adjust_to_mem_block(size);
+
+ // first pass of loop never has to initialize the slot in _available_heap
+ uint32_t needs_init = 0;
+ char* buffer = nullptr;
+ memory* current = nullptr;
+ // need to make sure
+ if (_active_heap < _heaps_actual_size)
+ {
+ memory* const start_heap = &_available_heaps[_active_heap];
+ // only heap 0 won't be initialized already
+ if(_active_heap == 0 && !start_heap->is_init())
+ {
+ start_heap->init(_initial_heap, _initial_heap_size);
+ }
+
+ current = start_heap;
+ }
+
+ while (current != nullptr)
+ {
+ buffer = current->malloc(size);
+ // done if we have a buffer
+ if (buffer != nullptr)
+ break;
+
+ current = next_active_heap();
+ }
+
+ if (buffer == nullptr)
+ {
+ const uint32_t end_free_heap = _active_free_heap;
+
+ do
+ {
+ buffer = _available_heaps[_active_free_heap].malloc_from_freed(size);
+
+ if (buffer != nullptr)
+ break;
+
+ if (++_active_free_heap == _heaps_actual_size)
+ _active_free_heap = 0;
+
+ } while (_active_free_heap != end_free_heap);
+ }
+
+ return buffer;
+ }
+
+ void* realloc(void* ptr, uint32_t size)
+ {
+ if (size == 0)
+ {
+ free(ptr);
+ return nullptr;
+ }
+
+ const uint32_t REMOVE = size;
+ adjust_to_mem_block(size);
+
+ char* realloc_ptr = nullptr;
+ uint32_t orig_ptr_size = 0;
+ if (ptr != nullptr)
+ {
+ char* const char_ptr = static_cast(ptr);
+ for (memory* realloc_heap = _available_heaps; realloc_heap < _available_heaps + _heaps_actual_size && realloc_heap->is_init(); ++realloc_heap)
+ {
+ if (realloc_heap->is_in_heap(char_ptr))
+ {
+ realloc_ptr = realloc_heap->realloc_in_place(char_ptr, size, &orig_ptr_size);
+
+ if (realloc_ptr != nullptr)
+ return realloc_ptr;
+ else
+ break;
+ }
+ }
+ }
+
+ char* new_alloc = static_cast(malloc(size));
+ if (new_alloc == nullptr)
+ return nullptr;
+
+ const uint32_t copy_size = (size < orig_ptr_size) ? size : orig_ptr_size;
+ if (copy_size > 0)
+ {
+ memcpy(new_alloc, ptr, copy_size);
+ free (ptr);
+ }
+
+ return new_alloc;
+ }
+
+ void free(void* ptr)
+ {
+ if (ptr == nullptr)
+ return;
+
+ char* const char_ptr = static_cast(ptr);
+ for (memory* free_heap = _available_heaps; free_heap < _available_heaps + _heaps_actual_size && free_heap->is_init(); ++free_heap)
+ {
+ if (free_heap->is_in_heap(char_ptr))
+ {
+ free_heap->free(char_ptr);
+ break;
+ }
+ }
+ }
+
+ void adjust_to_mem_block(uint32_t& size)
+ {
+ const uint32_t remainder = (size + _size_marker) & _rem_mem_block_mask;
+ if (remainder > 0)
+ {
+ size += _mem_block - remainder;
+ }
+ }
+
+ class memory
+ {
+ public:
+ memory()
+ : _heap_size(0)
+ , _heap(nullptr)
+ , _offset(0)
+ {
+ }
+
+ void init(char* const mem_heap, uint32_t size)
+ {
+ _heap_size = size;
+ _heap = mem_heap;
+ memset(_heap, 0, _heap_size);
+ }
+
+ uint32_t is_init() const
+ {
+ return _heap != nullptr;
+ }
+
+ uint32_t is_in_heap(const char* const ptr) const
+ {
+ const char* const end_of_buffer = _heap + _heap_size;
+ const char* const first_ptr_of_buffer = _heap + _size_marker;
+ return ptr >= first_ptr_of_buffer && ptr < end_of_buffer;
+ }
+
+ uint32_t is_capacity_remaining() const
+ {
+ return _offset + _size_marker < _heap_size;
+ }
+
+ char* malloc(uint32_t size)
+ {
+ uint32_t used_up_size = _offset + size + _size_marker;
+ if (used_up_size > _heap_size)
+ {
+ return nullptr;
+ }
+
+ buffer_ptr new_buff(&_heap[_offset + _size_marker], size, _heap + _heap_size);
+ _offset += size + _size_marker;
+ new_buff.mark_alloc();
+ return new_buff.ptr();
+ }
+
+ char* malloc_from_freed(uint32_t size)
+ {
+ eos_assert(_offset == _heap_size, "malloc_from_freed was designed to only be called after _heap was completely allocated");
+
+ char* current = _heap + _size_marker;
+ while (current != nullptr)
+ {
+ buffer_ptr current_buffer(current, _heap + _heap_size);
+ if (!current_buffer.is_alloc())
+ {
+ // done if we have enough contiguous memory
+ if (current_buffer.merge_contiguous(size))
+ {
+ current_buffer.mark_alloc();
+ return current;
+ }
+ }
+
+ current = current_buffer.next_ptr();
+ }
+
+ // failed to find any free memory
+ return nullptr;
+ }
+
+ char* realloc_in_place(char* const ptr, uint32_t size, uint32_t* orig_ptr_size)
+ {
+ const char* const end_of_buffer = _heap + _heap_size;
+
+ buffer_ptr orig_buffer(ptr, end_of_buffer);
+ *orig_ptr_size = orig_buffer.size();
+ // is the passed in pointer valid
+ char* const orig_buffer_end = orig_buffer.end();
+ if (orig_buffer_end > end_of_buffer)
+ {
+ *orig_ptr_size = 0;
+ return nullptr;
+ }
+
+ if (ptr > end_of_buffer - size)
+ {
+ // cannot resize in place
+ return nullptr;
+ }
+
+ const int32_t diff = size - *orig_ptr_size;
+ if (diff < 0)
+ {
+ // use a buffer_ptr to allocate the memory to free
+ char* const new_ptr = ptr + size + _size_marker;
+ buffer_ptr excess_to_free(new_ptr, -diff, _heap + _heap_size);
+ excess_to_free.mark_free();
+
+ return ptr;
+ }
+ // if ptr was the last allocated buffer, we can expand
+ else if (orig_buffer_end == &_heap[_offset])
+ {
+ orig_buffer.size(size);
+ _offset += diff;
+
+ return ptr;
+ }
+ if (-diff == 0)
+ return ptr;
+
+ if (!orig_buffer.merge_contiguous_if_available(size))
+ // could not resize in place
+ return nullptr;
+
+ orig_buffer.mark_alloc();
+ return ptr;
+ }
+
+ void free(char* ptr)
+ {
+ buffer_ptr to_free(ptr, _heap + _heap_size);
+ to_free.mark_free();
+ }
+
+ void cleanup_remaining()
+ {
+ if (_offset == _heap_size)
+ return;
+
+ // take the remaining memory and act like it was allocated
+ const uint32_t size = _heap_size - _offset - _size_marker;
+ buffer_ptr new_buff(&_heap[_offset + _size_marker], size, _heap + _heap_size);
+ _offset = _heap_size;
+ new_buff.mark_free();
+ }
+
+ bool expand_memory(char* exp_mem, uint32_t size)
+ {
+ if (_heap + _heap_size != exp_mem)
+ return false;
+
+ _heap_size += size;
+
+ return true;
+ }
+
+ private:
+ class buffer_ptr
+ {
+ public:
+ buffer_ptr(void* ptr, const char* const heap_end)
+ : _ptr(static_cast(ptr))
+ , _size(*reinterpret_cast(static_cast(ptr) - _size_marker) & ~_alloc_memory_mask)
+ , _heap_end(heap_end)
+ {
+ }
+
+ buffer_ptr(void* ptr, uint32_t buff_size, const char* const heap_end)
+ : _ptr(static_cast(ptr))
+ , _heap_end(heap_end)
+ {
+ size(buff_size);
+ }
+
+ uint32_t size() const
+ {
+ return _size;
+ }
+
+ char* next_ptr() const
+ {
+ char* const next = end() + _size_marker;
+ if (next >= _heap_end)
+ return nullptr;
+
+ return next;
+ }
+
+ void size(uint32_t val)
+ {
+ // keep the same state (allocated or free) as was set before
+ const uint32_t memory_state = *reinterpret_cast(_ptr - _size_marker) & _alloc_memory_mask;
+ *reinterpret_cast(_ptr - _size_marker) = val | memory_state;
+ _size = val;
+ }
+
+ char* end() const
+ {
+ return _ptr + _size;
+ }
+
+ char* ptr() const
+ {
+ return _ptr;
+ }
+
+ void mark_alloc()
+ {
+ *reinterpret_cast(_ptr - _size_marker) |= _alloc_memory_mask;
+ }
+
+ void mark_free()
+ {
+ *reinterpret_cast(_ptr - _size_marker) &= ~_alloc_memory_mask;
+ }
+
+ bool is_alloc() const
+ {
+ return *reinterpret_cast(_ptr - _size_marker) & _alloc_memory_mask;
+ }
+
+ bool merge_contiguous_if_available(uint32_t needed_size)
+ {
+ return merge_contiguous(needed_size, true);
+ }
+
+ bool merge_contiguous(uint32_t needed_size)
+ {
+ return merge_contiguous(needed_size, false);
+ }
+ private:
+ bool merge_contiguous(uint32_t needed_size, bool all_or_nothing)
+ {
+ // do not bother if there isn't contiguious space to allocate
+ if (all_or_nothing && _heap_end - _ptr < needed_size)
+ return false;
+
+ uint32_t possible_size = _size;
+ while (possible_size < needed_size && (_ptr + possible_size < _heap_end))
+ {
+ const uint32_t next_mem_flag_size = *reinterpret_cast(_ptr + possible_size);
+ // if ALLOCed then done with contiguous free memory
+ if (next_mem_flag_size & _alloc_memory_mask)
+ break;
+
+ possible_size += (next_mem_flag_size & ~_alloc_memory_mask) + _size_marker;
+ }
+
+ if (all_or_nothing && possible_size < needed_size)
+ return false;
+
+ // combine
+ const uint32_t new_size = possible_size < needed_size ? possible_size : needed_size;
+ size(new_size);
+
+ if (possible_size > needed_size)
+ {
+ const uint32_t freed_size = possible_size - needed_size - _size_marker;
+ buffer_ptr freed_remainder(_ptr + needed_size + _size_marker, freed_size, _heap_end);
+ freed_remainder.mark_free();
+ }
+
+ return new_size == needed_size;
+ }
+
+ char* _ptr;
+ uint32_t _size;
+ const char* const _heap_end;
+ };
+
+ uint32_t _heap_size;
+ char* _heap;
+ uint32_t _offset;
+ };
+
+ static const uint32_t _size_marker = sizeof(uint32_t);
+ // allocate memory in 8 char blocks
+ static const uint32_t _mem_block = 8;
+ static const uint32_t _rem_mem_block_mask = _mem_block - 1;
+ static const uint32_t _initial_heap_size = 8192;//32768;
+ static const uint32_t _new_heap_size = 65536;
+ // if sbrk is not called outside of this file, then this is the max times we can call it
+ static const uint32_t _heaps_size = 16;
+ char _initial_heap[_initial_heap_size];
+ memory _available_heaps[_heaps_size];
+ uint32_t _heaps_actual_size;
+ uint32_t _active_heap;
+ uint32_t _active_free_heap;
+ static const uint32_t _alloc_memory_mask = 1 << 31;
+ };
+
+ memory_manager memory_heap;
+}
+
+extern "C" {
+
+void* __dso_handle = 0;
+
+void* malloc(size_t size)
+{
+ return eosio::memory_heap.malloc(size);
+}
+
+void* calloc(size_t count, size_t size)
+{
+ return eosio::memory_heap.malloc(count*size);
+}
+
+void* realloc(void* ptr, size_t size)
+{
+ return eosio::memory_heap.realloc(ptr, size);
+}
+
+void free(void* ptr)
+{
+ return eosio::memory_heap.free(ptr);
+}
+
+}
diff --git a/contracts/eosiolib/generic_currency.hpp b/contracts/eosiolib/generic_currency.hpp
index fe0f4e35f0084b7d9eb504415b37875428c62f33..995ed870ed06826c1ef7fff7393bf41e314a0c37 100644
--- a/contracts/eosiolib/generic_currency.hpp
+++ b/contracts/eosiolib/generic_currency.hpp
@@ -41,7 +41,7 @@ namespace eosio {
template
friend DataStream& operator >> ( DataStream& ds, transfer& t ){
ds >> t.from >> t.to >> t.quantity;
- assert( t.quantity.symbol== token_type::symbol, "unexpected asset type" );
+ eos_assert( t.quantity.symbol== token_type::symbol, "unexpected asset type" );
return ds;
}
};
diff --git a/contracts/eosiolib/mainpage.md b/contracts/eosiolib/mainpage.md
index 92205cb5111a217800cb9dbc99a3368c49026f51..971e8698e9214d083e534aec0126bf9c8fd9b528 100644
--- a/contracts/eosiolib/mainpage.md
+++ b/contracts/eosiolib/mainpage.md
@@ -34,4 +34,4 @@ Welcome to the EOS.IO Documentation
- @ref transactionapi - Define API for sending transactions and inline messages
- @ref types - Specifies typedefs and aliases
-
\ No newline at end of file
+
diff --git a/contracts/eosiolib/math.hpp b/contracts/eosiolib/math.hpp
index 46e57dda5f520d9ea8b3251bdc8f8b52d8d6c4a1..eec8dff7e09162904fb3264a2582aea2258e15f6 100644
--- a/contracts/eosiolib/math.hpp
+++ b/contracts/eosiolib/math.hpp
@@ -102,7 +102,7 @@ namespace eosio {
}
explicit operator uint64_t()const {
- assert( !(value >> 64), "cast to 64 bit loss of precision" );
+ eos_assert( !(value >> 64), "cast to 64 bit loss of precision" );
return uint64_t(value);
}
diff --git a/contracts/eosiolib/memory.h b/contracts/eosiolib/memory.h
index 0cb326c0ab12e0e636127e179327655ae647d023..58e5a482b3d38b762de4b242b01bc43fdc40474b 100644
--- a/contracts/eosiolib/memory.h
+++ b/contracts/eosiolib/memory.h
@@ -4,89 +4,5 @@
*/
#pragma once
+#include
#include
-
-/**
- * @defgroup memoryapi Memory API
- * @brief Defines common memory functions
- * @ingroup contractdev
- */
-
-extern "C" {
- /**
- * @defgroup memorycapi Memory C API
- * @brief Defines common memory functions
- * @ingroup memoryapi
- *
- * @{
- */
-
- /**
- * Allocate page(s) of memory to accommodate the
- * requested number of bytes.
- * @brief Allocate page memory
- * @param num_bytes Number of bytes to add.
- *
- * @return void pointer to the previous end of allocated bytes
- *
- * Example:
- * @code
- * // allocate a whole new page, the returned offset is the pointer to the
- * // newly allocated page
- * char* new_page = static_cast(sbrk(65536));
- * memset(new_page, 0, 65536);
- * @endcode
- */
- void* sbrk( uint32_t num_bytes );
-
- /**
- * Copy a block of memory from source to destination.
- * @brief Copy a block of memory from source to destination.
- * @param destination Pointer to the destination to copy to.
- * @param source Pointer to the source for copy from.
- * @param num Number of bytes to copy.
- *
- * @return the destination pointer
- *
- * Example:
- * @code
- * char dest[6] = { 0 };
- * char source[6] = { 'H', 'e', 'l', 'l', 'o', '\0' };
- * memcpy(dest, source, 6 * sizeof(char));
- * prints(dest); // Output: Hello
- * @endcode
- */
- void* memcpy( void* destination, const void* source, uint32_t num );
-
- /**
- * Compare block of memory from source to destination.
- * @brief Copy a block of memory from source to destination.
- * @param ptr1 Pointer to first data to compare
- * @param ptr2 Pointer to second data to compare
- * @param num Number of bytes to compare.
- *
- * @return the destination pointer
- *
- */
- int32_t memcmp( void* ptr1, const void* ptr2, uint32_t num );
-
-
- /**
- * Fill block of memory.
- * @brief Fill a block of memory with the provided value.
- * @param ptr Pointer to memory to fill.
- * @param value Value to set (it is passed as an int but converted to unsigned char).
- * @param num Number of bytes to be set to the value.
- *
- * @return the destination pointer
- *
- * Example:
- * @code
- * char ptr[6] = { 'H', 'e', 'l', 'l', 'o', '\0' };
- * memset(ptr, 'y', 6 * sizeof(char));
- * prints(ptr); // Output: yyyyyy
- * @endcode
- */
- void* memset( void* ptr, uint32_t value, uint32_t num );
- /// @}
-} // extern "C"
diff --git a/contracts/eosiolib/memory.hpp b/contracts/eosiolib/memory.hpp
index 89041f15dfda1c7f8c27a096b725c388a0ad7ef2..57adc7320a67896d3f557a81154fa427d7fb4d5b 100644
--- a/contracts/eosiolib/memory.hpp
+++ b/contracts/eosiolib/memory.hpp
@@ -7,528 +7,16 @@
#include
#include
-namespace eosio {
+#include
- using ::memset;
- using ::memcpy;
+extern "C" {
- /**
- * @defgroup memorycppapi Memory C++ API
- * @brief Defines common memory functions
- * @ingroup memoryapi
- *
- * @{
- */
+void* malloc(size_t size);
- class memory_manager // NOTE: Should never allocate another instance of memory_manager
- {
- friend void* malloc(uint32_t size);
- friend void* realloc(void* ptr, uint32_t size);
- friend void free(void* ptr);
- public:
- memory_manager()
- // NOTE: it appears that WASM has an issue with initialization lists if the object is globally allocated,
- // and seems to just initialize members to 0
- : _heaps_actual_size(0)
- , _active_heap(0)
- , _active_free_heap(0)
- {
- }
+void* calloc(size_t count, size_t size);
- private:
- class memory;
+void* realloc(void* ptr, size_t size);
- memory* next_active_heap()
- {
- memory* const current_memory = _available_heaps + _active_heap;
+void free(void* ptr);
- // make sure we will not exceed the 1M limit (needs to match wasm_interface.cpp _max_memory)
- auto remaining = 1024 * 1024 - reinterpret_cast(sbrk(0));
- if (remaining <= 0)
- {
- // ensure that any remaining unallocated memory gets cleaned up
- current_memory->cleanup_remaining();
- ++_active_heap;
- _heaps_actual_size = _active_heap;
- return nullptr;
- }
-
- const uint32_t new_heap_size = remaining > _new_heap_size ? _new_heap_size : remaining;
- char* new_memory_start = static_cast(sbrk(new_heap_size));
- // if we can expand the current memory, keep working with it
- if (current_memory->expand_memory(new_memory_start, new_heap_size))
- return current_memory;
-
- // ensure that any remaining unallocated memory gets cleaned up
- current_memory->cleanup_remaining();
-
- ++_active_heap;
- memory* const next = _available_heaps + _active_heap;
- next->init(new_memory_start, new_heap_size);
-
- return next;
- }
-
- void* malloc(uint32_t size)
- {
- if (size == 0)
- return nullptr;
-
- // see Note on ctor
- if (_heaps_actual_size == 0)
- _heaps_actual_size = _heaps_size;
-
- adjust_to_mem_block(size);
-
- // first pass of loop never has to initialize the slot in _available_heap
- uint32_t needs_init = 0;
- char* buffer = nullptr;
- memory* current = nullptr;
- // need to make sure
- if (_active_heap < _heaps_actual_size)
- {
- memory* const start_heap = &_available_heaps[_active_heap];
- // only heap 0 won't be initialized already
- if(_active_heap == 0 && !start_heap->is_init())
- {
- start_heap->init(_initial_heap, _initial_heap_size);
- }
-
- current = start_heap;
- }
-
- while (current != nullptr)
- {
- buffer = current->malloc(size);
- // done if we have a buffer
- if (buffer != nullptr)
- break;
-
- current = next_active_heap();
- }
-
- if (buffer == nullptr)
- {
- const uint32_t end_free_heap = _active_free_heap;
-
- do
- {
- buffer = _available_heaps[_active_free_heap].malloc_from_freed(size);
-
- if (buffer != nullptr)
- break;
-
- if (++_active_free_heap == _heaps_actual_size)
- _active_free_heap = 0;
-
- } while (_active_free_heap != end_free_heap);
- }
-
- return buffer;
- }
-
- void* realloc(void* ptr, uint32_t size)
- {
- if (size == 0)
- {
- free(ptr);
- return nullptr;
- }
-
- const uint32_t REMOVE = size;
- adjust_to_mem_block(size);
-
- char* realloc_ptr = nullptr;
- uint32_t orig_ptr_size = 0;
- if (ptr != nullptr)
- {
- char* const char_ptr = static_cast(ptr);
- for (memory* realloc_heap = _available_heaps; realloc_heap < _available_heaps + _heaps_actual_size && realloc_heap->is_init(); ++realloc_heap)
- {
- if (realloc_heap->is_in_heap(char_ptr))
- {
- realloc_ptr = realloc_heap->realloc_in_place(char_ptr, size, &orig_ptr_size);
-
- if (realloc_ptr != nullptr)
- return realloc_ptr;
- else
- break;
- }
- }
- }
-
- char* new_alloc = static_cast(malloc(size));
- if (new_alloc == nullptr)
- return nullptr;
-
- const uint32_t copy_size = (size < orig_ptr_size) ? size : orig_ptr_size;
- if (copy_size > 0)
- {
- memcpy(new_alloc, ptr, copy_size);
- free (ptr);
- }
-
- return new_alloc;
- }
-
- void free(void* ptr)
- {
- if (ptr == nullptr)
- return;
-
- char* const char_ptr = static_cast(ptr);
- for (memory* free_heap = _available_heaps; free_heap < _available_heaps + _heaps_actual_size && free_heap->is_init(); ++free_heap)
- {
- if (free_heap->is_in_heap(char_ptr))
- {
- free_heap->free(char_ptr);
- break;
- }
- }
- }
-
- void adjust_to_mem_block(uint32_t& size)
- {
- const uint32_t remainder = (size + _size_marker) & _rem_mem_block_mask;
- if (remainder > 0)
- {
- size += _mem_block - remainder;
- }
- }
-
- class memory
- {
- public:
- memory()
- : _heap_size(0)
- , _heap(nullptr)
- , _offset(0)
- {
- }
-
- void init(char* const mem_heap, uint32_t size)
- {
- _heap_size = size;
- _heap = mem_heap;
- memset(_heap, 0, _heap_size);
- }
-
- uint32_t is_init() const
- {
- return _heap != nullptr;
- }
-
- uint32_t is_in_heap(const char* const ptr) const
- {
- const char* const end_of_buffer = _heap + _heap_size;
- const char* const first_ptr_of_buffer = _heap + _size_marker;
- return ptr >= first_ptr_of_buffer && ptr < end_of_buffer;
- }
-
- uint32_t is_capacity_remaining() const
- {
- return _offset + _size_marker < _heap_size;
- }
-
- char* malloc(uint32_t size)
- {
- uint32_t used_up_size = _offset + size + _size_marker;
- if (used_up_size > _heap_size)
- {
- return nullptr;
- }
-
- buffer_ptr new_buff(&_heap[_offset + _size_marker], size, _heap + _heap_size);
- _offset += size + _size_marker;
- new_buff.mark_alloc();
- return new_buff.ptr();
- }
-
- char* malloc_from_freed(uint32_t size)
- {
- assert(_offset == _heap_size, "malloc_from_freed was designed to only be called after _heap was completely allocated");
-
- char* current = _heap + _size_marker;
- while (current != nullptr)
- {
- buffer_ptr current_buffer(current, _heap + _heap_size);
- if (!current_buffer.is_alloc())
- {
- // done if we have enough contiguous memory
- if (current_buffer.merge_contiguous(size))
- {
- current_buffer.mark_alloc();
- return current;
- }
- }
-
- current = current_buffer.next_ptr();
- }
-
- // failed to find any free memory
- return nullptr;
- }
-
- char* realloc_in_place(char* const ptr, uint32_t size, uint32_t* orig_ptr_size)
- {
- const char* const end_of_buffer = _heap + _heap_size;
-
- buffer_ptr orig_buffer(ptr, end_of_buffer);
- *orig_ptr_size = orig_buffer.size();
- // is the passed in pointer valid
- char* const orig_buffer_end = orig_buffer.end();
- if (orig_buffer_end > end_of_buffer)
- {
- *orig_ptr_size = 0;
- return nullptr;
- }
-
- if (ptr > end_of_buffer - size)
- {
- // cannot resize in place
- return nullptr;
- }
-
- const int32_t diff = size - *orig_ptr_size;
- if (diff < 0)
- {
- // use a buffer_ptr to allocate the memory to free
- char* const new_ptr = ptr + size + _size_marker;
- buffer_ptr excess_to_free(new_ptr, -diff, _heap + _heap_size);
- excess_to_free.mark_free();
-
- return ptr;
- }
- // if ptr was the last allocated buffer, we can expand
- else if (orig_buffer_end == &_heap[_offset])
- {
- orig_buffer.size(size);
- _offset += diff;
-
- return ptr;
- }
- if (-diff == 0)
- return ptr;
-
- if (!orig_buffer.merge_contiguous_if_available(size))
- // could not resize in place
- return nullptr;
-
- orig_buffer.mark_alloc();
- return ptr;
- }
-
- void free(char* ptr)
- {
- buffer_ptr to_free(ptr, _heap + _heap_size);
- to_free.mark_free();
- }
-
- void cleanup_remaining()
- {
- if (_offset == _heap_size)
- return;
-
- // take the remaining memory and act like it was allocated
- const uint32_t size = _heap_size - _offset - _size_marker;
- buffer_ptr new_buff(&_heap[_offset + _size_marker], size, _heap + _heap_size);
- _offset = _heap_size;
- new_buff.mark_free();
- }
-
- bool expand_memory(char* exp_mem, uint32_t size)
- {
- if (_heap + _heap_size != exp_mem)
- return false;
-
- _heap_size += size;
-
- return true;
- }
-
- private:
- class buffer_ptr
- {
- public:
- buffer_ptr(void* ptr, const char* const heap_end)
- : _ptr(static_cast(ptr))
- , _size(*reinterpret_cast(static_cast(ptr) - _size_marker) & ~_alloc_memory_mask)
- , _heap_end(heap_end)
- {
- }
-
- buffer_ptr(void* ptr, uint32_t buff_size, const char* const heap_end)
- : _ptr(static_cast(ptr))
- , _heap_end(heap_end)
- {
- size(buff_size);
- }
-
- uint32_t size() const
- {
- return _size;
- }
-
- char* next_ptr() const
- {
- char* const next = end() + _size_marker;
- if (next >= _heap_end)
- return nullptr;
-
- return next;
- }
-
- void size(uint32_t val)
- {
- // keep the same state (allocated or free) as was set before
- const uint32_t memory_state = *reinterpret_cast(_ptr - _size_marker) & _alloc_memory_mask;
- *reinterpret_cast(_ptr - _size_marker) = val | memory_state;
- _size = val;
- }
-
- char* end() const
- {
- return _ptr + _size;
- }
-
- char* ptr() const
- {
- return _ptr;
- }
-
- void mark_alloc()
- {
- *reinterpret_cast(_ptr - _size_marker) |= _alloc_memory_mask;
- }
-
- void mark_free()
- {
- *reinterpret_cast(_ptr - _size_marker) &= ~_alloc_memory_mask;
- }
-
- bool is_alloc() const
- {
- return *reinterpret_cast(_ptr - _size_marker) & _alloc_memory_mask;
- }
-
- bool merge_contiguous_if_available(uint32_t needed_size)
- {
- return merge_contiguous(needed_size, true);
- }
-
- bool merge_contiguous(uint32_t needed_size)
- {
- return merge_contiguous(needed_size, false);
- }
- private:
- bool merge_contiguous(uint32_t needed_size, bool all_or_nothing)
- {
- // do not bother if there isn't contiguious space to allocate
- if (all_or_nothing && _heap_end - _ptr < needed_size)
- return false;
-
- uint32_t possible_size = _size;
- while (possible_size < needed_size && (_ptr + possible_size < _heap_end))
- {
- const uint32_t next_mem_flag_size = *reinterpret_cast(_ptr + possible_size);
- // if ALLOCed then done with contiguous free memory
- if (next_mem_flag_size & _alloc_memory_mask)
- break;
-
- possible_size += (next_mem_flag_size & ~_alloc_memory_mask) + _size_marker;
- }
-
- if (all_or_nothing && possible_size < needed_size)
- return false;
-
- // combine
- const uint32_t new_size = possible_size < needed_size ? possible_size : needed_size;
- size(new_size);
-
- if (possible_size > needed_size)
- {
- const uint32_t freed_size = possible_size - needed_size - _size_marker;
- buffer_ptr freed_remainder(_ptr + needed_size + _size_marker, freed_size, _heap_end);
- freed_remainder.mark_free();
- }
-
- return new_size == needed_size;
- }
-
- char* _ptr;
- uint32_t _size;
- const char* const _heap_end;
- };
-
- uint32_t _heap_size;
- char* _heap;
- uint32_t _offset;
- };
-
- static const uint32_t _size_marker = sizeof(uint32_t);
- // allocate memory in 8 char blocks
- static const uint32_t _mem_block = 8;
- static const uint32_t _rem_mem_block_mask = _mem_block - 1;
- static const uint32_t _initial_heap_size = 8192;//32768;
- static const uint32_t _new_heap_size = 65536;
- // if sbrk is not called outside of this file, then this is the max times we can call it
- static const uint32_t _heaps_size = 16;
- char _initial_heap[_initial_heap_size];
- memory _available_heaps[_heaps_size];
- uint32_t _heaps_actual_size;
- uint32_t _active_heap;
- uint32_t _active_free_heap;
- static const uint32_t _alloc_memory_mask = 1 << 31;
- } memory_heap;
-
- /**
- * Allocate a block of memory.
- * @brief Allocate a block of memory.
- * @param size Size of memory block
- *
- * Example:
- * @code
- * uint64_t* int_buffer = malloc(500 * sizeof(uint64_t));
- * @endcode
- */
- inline void* malloc(uint32_t size)
- {
- return memory_heap.malloc(size);
- }
-
- /**
- * Allocate a block of memory.
- * @brief Allocate a block of memory.
- * @param size Size of memory block
- *
- * Example:
- * @code
- * uint64_t* int_buffer = malloc(500 * sizeof(uint64_t));
- * ...
- * uint64_t* bigger_int_buffer = realloc(int_buffer, 600 * sizeof(uint64_t));
- * @endcode
- */
-
- inline void* realloc(void* ptr, uint32_t size)
- {
- return memory_heap.realloc(ptr, size);
- }
-
- /**
- * Free a block of memory.
- * @brief Free a block of memory.
- * @param ptr Pointer to memory block to free.
- *
- * Example:
- * @code
- * uint64_t* int_buffer = malloc(500 * sizeof(uint64_t));
- * ...
- * free(int_buffer);
- * @endcode
- */
- inline void free(void* ptr)
- {
- return memory_heap.free(ptr);
- }
- /// @} /// mathcppapi
}
diff --git a/contracts/eosiolib/print.h b/contracts/eosiolib/print.h
index 3d6fb894c79e60e8d9d3451d3cbd680c3cc5586f..1f2606e257ee4ba65c6c2c07279a1a863a542e70 100644
--- a/contracts/eosiolib/print.h
+++ b/contracts/eosiolib/print.h
@@ -4,7 +4,11 @@
*/
#pragma once
+#include
+
+#ifdef __cplusplus
extern "C" {
+#endif
/**
* @defgroup consoleapi Console API
* @brief Enables applications to log/print text messages
@@ -98,4 +102,6 @@ extern "C" {
*/
void printhex( void* data, uint32_t datalen );
/// @}
+#ifdef __cplusplus
}
+#endif
diff --git a/contracts/eosiolib/singleton.hpp b/contracts/eosiolib/singleton.hpp
index 5676509d5b9a31d81795c539be7ae9abdb432d8f..a30e220b95d0ebab7e7809882fef0305a91067ba 100644
--- a/contracts/eosiolib/singleton.hpp
+++ b/contracts/eosiolib/singleton.hpp
@@ -19,20 +19,26 @@ namespace eosio {
static bool exists( scope_name scope = Code ) {
uint64_t key = SingletonName;
- auto read = load_i64( scope, Code, key, (char*)&key, sizeof(key) );
+ auto read = load_i64( Code, scope, key, (char*)&key, sizeof(key) );
return read > 0;
}
static T get( scope_name scope = Code ) {
char temp[1024+8];
*reinterpret_cast(temp) = SingletonName;
- auto read = load_i64( scope, Code, SingletonName, temp, sizeof(temp) );
- assert( read > 0, "singleton does not exist" );
- datastream ds(temp + sizeof(SingletonName), read);
+ auto read = load_i64( Code, scope, SingletonName, temp, sizeof(temp) );
+ eos_assert( read > 0, "singleton does not exist" );
+ return unpack( temp + sizeof(SingletonName), read );
+ }
- T result;
- unpack( ds, result );
- return result;
+ static T get_or_default( scope_name scope = Code, const T& def = T() ) {
+ char temp[1024+8];
+ *reinterpret_cast(temp) = SingletonName;
+ auto read = load_i64( Code, scope, SingletonName, temp, sizeof(temp) );
+ if ( read < 0 ) {
+ return def;
+ }
+ return unpack( temp + sizeof(SingletonName), read );
}
static T get_or_create( scope_name scope = Code, const T& def = T() ) {
@@ -40,23 +46,19 @@ namespace eosio {
*reinterpret_cast(temp) = SingletonName;
- auto read = load_i64( scope, Code, SingletonName, temp, sizeof(temp) );
+ auto read = load_i64( Code, scope, SingletonName, temp, sizeof(temp) );
if( read < 0 ) {
set( def, scope );
return def;
}
-
- datastream ds(temp + sizeof(SingletonName), read);
- T result;
- ds >> result;
- return result;
+ return unpack( temp + sizeof(SingletonName), read );
}
static void set( const T& value = T(), scope_name scope = Code, account_name b = BillToAccount ) {
auto size = pack_size( value );
char buf[size+ sizeof(SingletonName)];
- assert( sizeof(buf) <= 1024 + 8, "singleton too big to store" );
+ eos_assert( sizeof(buf) <= 1024 + 8, "singleton too big to store" );
datastream ds( buf, size + sizeof(SingletonName) );
ds << SingletonName;
@@ -64,6 +66,11 @@ namespace eosio {
store_i64( scope, SingletonName, b, buf, sizeof(buf) );
}
+
+ static void remove( scope_name scope = Code ) {
+ uint64_t key = SingletonName;
+ remove_i64( scope, SingletonName, &key );
+ }
};
} /// namespace eosio
diff --git a/contracts/eosiolib/stdlib.hpp b/contracts/eosiolib/stdlib.hpp
index d3baab2ecd5f4add9b8f0eced222334cf29dc36b..7fd8f86d525dcdc2813a710cf038baa39c24f9d8 100644
--- a/contracts/eosiolib/stdlib.hpp
+++ b/contracts/eosiolib/stdlib.hpp
@@ -1,44 +1,5 @@
#pragma once
-// forward declarations, to be filled in by the compiler, for placement new.
-extern "C" {
- void* operator new(size_t, void*);
- void* operator new[](size_t, void*);
-}
-
-// compatibility for things declared by the c++ standard libraries that compilers replace
-namespace std {
-
-// forward declaration of initializer_list
-template class initializer_list {
- public:
- using value_type = E;
- using reference = const E&;
- using const_reference = const E&;
- using size_type = size_t;
- using iterator = const E*;
- using const_iterator = const E*;
- constexpr initializer_list() noexcept;
- constexpr size_t size() const noexcept {
- return _len;
- }
- constexpr const E* begin() const noexcept {
- return _iter;
- }
- constexpr const E* end() const noexcept {
- return _iter + _len;
- }
-
- private:
- iterator _iter;
- size_type _len;
-
- constexpr initializer_list(const_iterator array, size_type len)
- :_iter(array),_len(len)
- {}
-};
-// initializer list range access
-template constexpr const E* begin(initializer_list il) noexcept;
-template constexpr const E* end(initializer_list il) noexcept;
-
-}
\ No newline at end of file
+#include
+#include
+#include
diff --git a/contracts/eosiolib/string.hpp b/contracts/eosiolib/string.hpp
index b5f7258562d4e2adca1bf5edbefced6d73cf3d25..502c0f5cac86f7ddd6fd253b8d55b485687239c3 100644
--- a/contracts/eosiolib/string.hpp
+++ b/contracts/eosiolib/string.hpp
@@ -4,6 +4,7 @@
#include
#include
#include
+#include
namespace eosio {
/**
@@ -197,12 +198,12 @@ namespace eosio {
* @return substring of the current string
*/
string substr(size_t offset, size_t substr_size, bool copy) {
- assert((offset < size) && (offset + substr_size < size), "out of bound");
+ eos_assert((offset < size) && (offset + substr_size < size), "out of bound");
return string(data + offset, substr_size, copy);
}
char operator [] (const size_t index) {
- assert(index < size, "index out of bound");
+ eos_assert(index < size, "index out of bound");
return *(data + index);
}
@@ -237,7 +238,7 @@ namespace eosio {
}
string& operator += (const string& str){
- assert((size + str.size > size) && (size + str.size > str.size), "overflow");
+ eos_assert((size + str.size > size) && (size + str.size > str.size), "overflow");
char* new_data;
size_t new_size;
diff --git a/contracts/eosiolib/system.h b/contracts/eosiolib/system.h
index d8183afff1efa33a9fba8a7cf83cf674f438a6d7..8b0723042f56c2345f028a913f494e852013b5da 100644
--- a/contracts/eosiolib/system.h
+++ b/contracts/eosiolib/system.h
@@ -29,7 +29,7 @@ extern "C" {
* @param cstr - a null terminated action to explain the reason for failure
*/
- void assert( uint32_t test, const char* cstr );
+ void eos_assert( uint32_t test, const char* cstr );
/**
* Returns the time in seconds from 1970 of the last accepted block (not the block including this action)
@@ -37,7 +37,27 @@ extern "C" {
* @return time in seconds from 1970 of the last accepted block
*/
time now();
-
///@ } systemcapi
+
+ /**
+ * @defgroup privilegedapi Privileged API
+ * @ingroup systemapi
+ * @brief Defines an API for accessing configuration of the chain that can only be done by privileged accounts
+ */
+
+ /**
+ * @defgroup privilegedcapi Privileged C API
+ * @ingroup privilegedapi
+ * @brief Define C Privileged API
+ *
+ * @{
+ */
+
+ void set_resource_limits( account_name account, int64_t ram_bytes, int64_t net_weight, int64_t cpu_weight, int64_t ignored);
+
+ void set_active_producers( char *producer_data, size_t producer_data_size );
+
+ ///@ } privilegedcapi
+
}
diff --git a/contracts/eosiolib/table.hpp b/contracts/eosiolib/table.hpp
index 579cda20c9b9dcb6996dc49dfeaba6d30a010c45..6ad28ec9a3949b717e8edb7899ac734b658fd6ed 100644
--- a/contracts/eosiolib/table.hpp
+++ b/contracts/eosiolib/table.hpp
@@ -21,7 +21,7 @@ namespace eosio {
char temp[1024];
*reinterpret_cast(temp) = key;
auto read = load_i64( DefaultScope, scope , TableName, temp, sizeof(temp) );
- assert( read > 0, "key does not exist" );
+ eos_assert( read > 0, "key does not exist" );
datastream ds(temp, read);
T result;
@@ -63,7 +63,7 @@ namespace eosio {
static void set( const T& value = T(), scope_name scope = DefaultScope, uint64_t bta = BillToAccount ) {
auto size = pack_size( value );
char buf[size];
- assert( size <= 1024, "singleton too big to store" );
+ eos_assert( size <= 1024, "singleton too big to store" );
datastream ds( buf, size );
ds << value;
@@ -93,7 +93,7 @@ namespace eosio {
temp[1] = secondary;
temp[2] = tertiary;
- auto read = lower_bound_primary_i64i64i64( Code, _scope, TableName,
+ auto read = lower_bound_primary_i64i64i64( Code, _scope, TableName,
(char*)temp, sizeof(temp) );
if( read <= 0 ) {
return false;
@@ -104,21 +104,31 @@ namespace eosio {
return true;
}
- bool next_primary( T& result, const T& current ) {
+ bool primary_upper_bound( T& result,
+ uint64_t primary = 0,
+ uint64_t secondary = 0,
+ uint64_t tertiary = 0 ) {
+
uint64_t temp[1024/8];
- memcpy( temp, (const char*)¤t, 3*sizeof(uint64_t) );
-
- auto read = next_primary_i64i64i64( Code, _scope, TableName,
+ temp[0] = primary;
+ temp[1] = secondary;
+ temp[2] = tertiary;
+
+ auto read = upper_bound_primary_i64i64i64( Code, _scope, TableName,
(char*)temp, sizeof(temp) );
if( read <= 0 ) {
return false;
}
- datastream ds( (char*)temp, sizeof(temp) );
- ds >> result;
+ result = unpack( (char*)temp, sizeof(temp) );
return true;
}
+ bool next_primary( T& result, const T& current ) {
+ const uint64_t* keys = reinterpret_cast(¤t);
+ return primary_upper_bound(result, keys[0], keys[1], keys[2]);
+ }
+
void store( const T& value, account_name bill_to = BillToAccount ) {
char temp[1024];
datastream ds(temp, sizeof(temp) );
diff --git a/contracts/eosiolib/token.hpp b/contracts/eosiolib/token.hpp
index ca9ecbe81f721bff798a2f22b4c97d5d171bb3b9..a922d23fa478cf30dd8d351b46fdbbbf2339b981 100644
--- a/contracts/eosiolib/token.hpp
+++ b/contracts/eosiolib/token.hpp
@@ -41,7 +41,7 @@ namespace eosio {
operator asset()const { return asset( quantity, Symbol ); }
token( const asset& a ):quantity(a.amount) {
- assert( a.symbol == Symbol, "attempt to construct token from asset with different symbol" );
+ eos_assert( a.symbol == Symbol, "attempt to construct token from asset with different symbol" );
}
/**
@@ -65,7 +65,7 @@ namespace eosio {
* @return this token after subtraction
*/
token& operator-=( const token& a ) {
- assert( quantity >= a.quantity, "integer underflow subtracting token balance" );
+ eos_assert( quantity >= a.quantity, "integer underflow subtracting token balance" );
quantity -= a.quantity;
return *this;
}
@@ -78,7 +78,7 @@ namespace eosio {
* @return this token after addition
*/
token& operator+=( const token& a ) {
- assert( quantity + a.quantity >= a.quantity, "integer overflow adding token balance" );
+ eos_assert( quantity + a.quantity >= a.quantity, "integer overflow adding token balance" );
quantity += a.quantity;
return *this;
}
@@ -258,8 +258,8 @@ namespace eosio {
* @param quote - quote token
*/
price( BaseToken base, QuoteToken quote ) {
- assert( base >= BaseToken(1ul), "invalid price" );
- assert( quote >= QuoteToken(1ul), "invalid price" );
+ eos_assert( base >= BaseToken(1ul), "invalid price" );
+ eos_assert( quote >= QuoteToken(1ul), "invalid price" );
base_per_quote = base.quantity;
base_per_quote *= precision;
diff --git a/contracts/eosiolib/types.h b/contracts/eosiolib/types.h
index 90ea234d42de87a85471574c927372b568fa7e0f..05be74311ab8c3eb9b18b774944269809232f020 100644
--- a/contracts/eosiolib/types.h
+++ b/contracts/eosiolib/types.h
@@ -4,7 +4,12 @@
*/
#pragma once
+#include
+#include
+
+#ifdef __cplusplus
extern "C" {
+#endif
/**
* @defgroup types Builtin Types
@@ -14,24 +19,10 @@ extern "C" {
* @{
*/
-typedef unsigned __int128 uint128_t;
-typedef unsigned long long uint64_t;
-typedef unsigned long uint32_t;
-typedef unsigned short uint16_t;
-typedef unsigned char uint8_t;
-
-typedef __int128 int128_t;
-typedef long long int64_t;
-typedef long int32_t;
-typedef short int16_t;
-typedef char int8_t;
-
struct uint256 {
uint64_t words[4];
};
-typedef unsigned int size_t;
-
typedef uint64_t account_name;
typedef uint64_t permission_name;
typedef uint64_t token_name;
@@ -60,22 +51,24 @@ struct checksum {
struct fixed_string16 {
uint8_t len;
- char str[16];
+ char str[16];
};
-typedef fixed_string16 field_name;
+typedef struct fixed_string16 field_name;
struct fixed_string32 {
uint8_t len;
- char str[32];
+ char str[32];
};
-typedef fixed_string32 type_name;
+typedef struct fixed_string32 type_name;
struct account_permission {
account_name account;
permission_name permission;
};
+#ifdef __cplusplus
} /// extern "C"
+#endif
/// @}
diff --git a/contracts/eosiolib/varint.hpp b/contracts/eosiolib/varint.hpp
index dbeb25a24d879bf6ebd12d096e4761c9cf8737cd..c931e4deac8199863952d7f6cd08d471cdc87725 100644
--- a/contracts/eosiolib/varint.hpp
+++ b/contracts/eosiolib/varint.hpp
@@ -126,4 +126,4 @@ struct signed_int {
}
};
-/// @}
\ No newline at end of file
+/// @}
diff --git a/contracts/exchange/CMakeLists.txt b/contracts/exchange/CMakeLists.txt
index 2abac50cd86904fc8f473ffea9805e400a95dba6..54913cb2f6544b438e7dc94033ec65f79180afc2 100644
--- a/contracts/exchange/CMakeLists.txt
+++ b/contracts/exchange/CMakeLists.txt
@@ -1,4 +1,8 @@
file(GLOB ABI_FILES "*.abi")
-add_wast_target(exchange "${CMAKE_SOURCE_DIR}/contracts" ${CMAKE_CURRENT_BINARY_DIR})
+add_wast_executable(TARGET exchange
+ INCLUDE_FOLDERS "${STANDARD_INCLUDE_FOLDERS}"
+ LIBRARIES eosiolib
+ DESTINATION_FOLDER ${CMAKE_CURRENT_BINARY_DIR}
+)
configure_file("${ABI_FILES}" "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY)
add_dependencies( exchange currency )
diff --git a/contracts/exchange/exchange.cpp b/contracts/exchange/exchange.cpp
index 3f312f7500f0827d5d049eda0bf47e99805481de..6c43b47d643a1ad731327b7f5c92474534a410c1 100644
--- a/contracts/exchange/exchange.cpp
+++ b/contracts/exchange/exchange.cpp
@@ -75,7 +75,7 @@ void apply_currency_transfer( const currency::transfer& transfer ) {
mod_account.currency_balance -= transfer.quantity;
});
} else {
- assert( false, "notified on transfer that is not relevant to this exchange" );
+ eos_assert( false, "notified on transfer that is not relevant to this exchange" );
}
}
@@ -95,7 +95,7 @@ void apply_eos_transfer( const eosio::transfer& transfer ) {
mod_account.eos_balance -= transfer.quantity;
});
} else {
- assert( false, "notified on transfer that is not relevant to this exchange" );
+ eos_assert( false, "notified on transfer that is not relevant to this exchange" );
}
}
@@ -132,13 +132,13 @@ void apply_exchange_buy( buy_order order ) {
bid& exchange_bid = order;
require_auth( exchange_bid.buyer.name );
- assert( exchange_bid.quantity > eosio::tokens(0), "invalid quantity" );
- assert( exchange_bid.expiration > now(), "order expired" );
+ eos_assert( exchange_bid.quantity > eosio::tokens(0), "invalid quantity" );
+ eos_assert( exchange_bid.expiration > now(), "order expired" );
print( name(exchange_bid.buyer.name), " created bid for ", order.quantity, " currency at price: ", order.at_price, "\n" );
bid existing_bid;
- assert( !bids_by_id::get( exchange_bid.buyer, existing_bid ), "order with this id already exists" );
+ eos_assert( !bids_by_id::get( exchange_bid.buyer, existing_bid ), "order with this id already exists" );
print( __FILE__, __LINE__, "\n" );
auto buyer_account = get_account( exchange_bid.buyer.name );
@@ -147,7 +147,7 @@ void apply_exchange_buy( buy_order order ) {
ask lowest_ask;
if( !asks_by_price::front( lowest_ask ) ) {
print( "\n No asks found, saving buyer account and storing bid\n" );
- assert( !order.fill_or_kill, "order not completely filled" );
+ eos_assert( !order.fill_or_kill, "order not completely filled" );
bids::store( exchange_bid );
buyer_account.open_orders++;
save( buyer_account );
@@ -183,7 +183,7 @@ void apply_exchange_buy( buy_order order ) {
print( "saving buyer's account\n" );
if( exchange_bid.quantity ) {
print( exchange_bid.quantity, " eos left over" );
- assert( !order.fill_or_kill, "order not completely filled" );
+ eos_assert( !order.fill_or_kill, "order not completely filled" );
bids::store( exchange_bid );
return;
}
@@ -195,14 +195,14 @@ void apply_exchange_sell( sell_order order ) {
ask& exchange_ask = order;
require_auth( exchange_ask.seller.name );
- assert( exchange_ask.quantity > currency_tokens(0), "invalid quantity" );
- assert( exchange_ask.expiration > now(), "order expired" );
+ eos_assert( exchange_ask.quantity > currency_tokens(0), "invalid quantity" );
+ eos_assert( exchange_ask.expiration > now(), "order expired" );
print( "\n\n", name(exchange_ask.seller.name), " created sell for ", order.quantity,
" currency at price: ", order.at_price, "\n");
ask existing_ask;
- assert( !asks_by_id::get( exchange_ask.seller, existing_ask ), "order with this id already exists" );
+ eos_assert( !asks_by_id::get( exchange_ask.seller, existing_ask ), "order with this id already exists" );
auto seller_account = get_account( exchange_ask.seller.name );
seller_account.currency_balance -= exchange_ask.quantity;
@@ -210,7 +210,7 @@ void apply_exchange_sell( sell_order order ) {
bid highest_bid;
if( !bids_by_price::back( highest_bid ) ) {
- assert( !order.fill_or_kill, "order not completely filled" );
+ eos_assert( !order.fill_or_kill, "order not completely filled" );
print( "\n No bids found, saving seller account and storing ask\n" );
asks::store( exchange_ask );
seller_account.open_orders++;
@@ -241,7 +241,7 @@ void apply_exchange_sell( sell_order order ) {
if( exchange_ask.quantity && !order.fill_or_kill ) seller_account.open_orders++;
save( seller_account );
if( exchange_ask.quantity ) {
- assert( !order.fill_or_kill, "order not completely filled" );
+ eos_assert( !order.fill_or_kill, "order not completely filled" );
print( "saving ask\n" );
asks::store( exchange_ask );
return;
@@ -254,7 +254,7 @@ void apply_exchange_cancel_buy( order_id order ) {
require_auth( order.name );
bid bid_to_cancel;
- assert( bids_by_id::get( order, bid_to_cancel ), "bid with this id does not exists" );
+ eos_assert( bids_by_id::get( order, bid_to_cancel ), "bid with this id does not exists" );
auto buyer_account = get_account( order.name );
buyer_account.eos_balance += bid_to_cancel.quantity;
@@ -270,7 +270,7 @@ void apply_exchange_cancel_sell( order_id order ) {
require_auth( order.name );
ask ask_to_cancel;
- assert( asks_by_id::get( order, ask_to_cancel ), "ask with this id does not exists" );
+ eos_assert( asks_by_id::get( order, ask_to_cancel ), "ask with this id does not exists" );
auto seller_account = get_account( order.name );
seller_account.currency_balance += ask_to_cancel.quantity;
@@ -307,7 +307,7 @@ extern "C" {
apply_exchange_cancel_sell( current_action() );
break;
default:
- assert( false, "unknown action" );
+ eos_assert( false, "unknown action" );
}
}
else if( code == N(currency) ) {
diff --git a/contracts/identity/CMakeLists.txt b/contracts/identity/CMakeLists.txt
index 363bbed0ebbff599d430980efe60d373b45d1be1..10e7b96b6dae16ea3164f9093d72f6db635ec2f7 100644
--- a/contracts/identity/CMakeLists.txt
+++ b/contracts/identity/CMakeLists.txt
@@ -1,5 +1,9 @@
file(GLOB ABI_FILES "*.abi")
configure_file("${ABI_FILES}" "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY)
-add_wast_target(identity "${CMAKE_SOURCE_DIR}/contracts" ${CMAKE_CURRENT_BINARY_DIR})
+add_wast_executable(TARGET identity
+ INCLUDE_FOLDERS "${STANDARD_INCLUDE_FOLDERS}"
+ LIBRARIES eosiolib
+ DESTINATION_FOLDER ${CMAKE_CURRENT_BINARY_DIR}
+)
add_subdirectory(test)
diff --git a/contracts/identity/identity.abi b/contracts/identity/identity.abi
index cb008b47aeb600119323a15eba17e14a8b417cd0..b07f79a4458b25efba2b0d70cba63fff22fab72f 100644
--- a/contracts/identity/identity.abi
+++ b/contracts/identity/identity.abi
@@ -62,18 +62,12 @@
{"name":"identity", "type":"uint64"},
{"name":"creator", "type":"account_name"}
]
- },{
- "name": "trustrow",
- "base": "",
- "fields": [
- {"name":"account", "type":"account_name"},
- {"name":"trusted", "type":"uint8"}
- ]
},{
"name": "accountrow",
"base": "",
"fields": [
- {"name":"account", "type":"account_name"}
+ {"name":"singleton_name", "type":"uint64"},
+ {"name":"identity", "type":"uint64"}
]
}
],
@@ -110,7 +104,7 @@
"key_types": [ "uint64" ]
},{
"name": "trust",
- "type": "trustrow",
+ "type": "account_name",
"index_type": "i64",
"key_names" : [ "account" ],
"key_types": [ "account_name" ]
diff --git a/contracts/identity/identity.hpp b/contracts/identity/identity.hpp
index f45f27d174ae558b87b20d2240ee0572fa8d5d8b..988162e7c458acee515cd3624c93a031592836aa 100644
--- a/contracts/identity/identity.hpp
+++ b/contracts/identity/identity.hpp
@@ -2,6 +2,7 @@
#include
#include
+#include
#include
#include
#include
@@ -10,6 +11,7 @@ namespace identity {
using eosio::action_meta;
using eosio::table_i64i64i64;
using eosio::table64;
+ using eosio::singleton;
using eosio::string;
using eosio::vector;
@@ -195,8 +197,8 @@ namespace identity {
typedef table_i64i64i64 certs_table;
typedef table64 idents_table;
- typedef table64 accounts_table;
- typedef table64 trust_table;
+ typedef singleton accounts_table;
+ typedef table64 trust_table;
static identity_name get_claimed_identity( account_name acnt ) {
return accounts_table::get_or_default(acnt, 0);
@@ -209,13 +211,19 @@ namespace identity {
certs_table certs( ident );
certrow row;
bool ok = certs.primary_lower_bound(row, N(owner), 1, 0);
+ account_name owner = 0;
while (ok && row.property == N(owner) && row.trusted) {
if (sizeof(account_name) == row.data.size()) {
account_name account = *reinterpret_cast(row.data.data());
if (ident == get_claimed_identity(account)) {
if (is_trusted(row.certifier) ) {
// the certifier is still trusted
- return account;
+ if (!owner || owner == account) {
+ owner = account;
+ } else {
+ //contradiction found: different owners certified for the same identity
+ return 0;
+ }
} else if (DeployToAccount == current_receiver()){
//the certifier is no longer trusted, need to unset the flag
row.trusted = 0;
@@ -227,8 +235,13 @@ namespace identity {
} else {
// bad row - skip it
}
+ //ok = certs.primary_upper_bound(row, row.property, row.trusted, row.certifier);
ok = certs.next_primary(row, row);
}
+ if (owner) {
+ //owner found, no contradictions among certifications flaged as trusted
+ return owner;
+ }
// trusted certification not found
// let's see if some of untrusted certifications became trusted
ok = certs.primary_lower_bound(row, N(owner), 0, 0);
@@ -236,18 +249,25 @@ namespace identity {
if (sizeof(account_name) == row.data.size()) {
account_name account = *reinterpret_cast(row.data.data());
if (ident == get_claimed_identity(account) && is_trusted(row.certifier)) {
- // the certifier became trusted, need to set the flag
- row.trusted = 1;
- certs.store( row, 0 ); //assuming 0 means bill to the same account
- return *reinterpret_cast(row.data.data());
+ if (DeployToAccount == current_receiver()) {
+ // the certifier became trusted and we have permissions to update the flag
+ row.trusted = 1;
+ certs.store( row, 0 ); //assuming 0 means bill to the same account
+ }
+ if (!owner || owner == account) {
+ owner = account;
+ } else {
+ //contradiction found: different owners certified for the same identity
+ return 0;
+ }
}
} else {
// bad row - skip it
}
+ //ok = certs.primary_upper_bound(row, row.property, row.trusted, row.certifier);
ok = certs.next_primary(row, row);
}
-
- return 0;
+ return owner;
}
static identity_name get_identity_for_account( account_name acnt ) {
@@ -258,10 +278,7 @@ namespace identity {
}
static bool is_trusted_by( account_name trusted, account_name by ) {
- trustrow def;
- def.trusted = 0;
- trustrow row = trust_table::get_or_default( trusted, by, def );
- return def.trusted;
+ return trust_table::exists(trusted, by);
}
static bool is_trusted( account_name acnt ) {
@@ -283,20 +300,16 @@ namespace identity {
require_recipient( t.trusting );
if( t.trust != 0 ) {
- trustrow row{ .account = t.trusting,
- .trusted = t.trust };
- trust_table::set( row, t.trustor );
+ trust_table::set( t.trusting, t.trustor );
} else {
- trustrow row{ .account = t.trusting,
- .trusted = t.trust };
- trust_table::remove( row.account, t.trustor );
+ trust_table::remove( t.trusting, t.trustor );
}
}
static void on( const create& c ) {
require_auth( c.creator );
- assert( !idents_table::exists( c.identity ), "identity already exists" );
- assert( c.identity != 0, "identity=0 is not allowed" );
+ eos_assert( !idents_table::exists( c.identity ), "identity already exists" );
+ eos_assert( c.identity != 0, "identity=0 is not allowed" );
idents_table::set( identrow{ .identity = c.identity,
.creator = c.creator } );
}
@@ -306,7 +319,7 @@ namespace identity {
if( cert.bill_storage_to != cert.certifier )
require_auth( cert.bill_storage_to );
- assert( idents_table::exists( cert.identity ), "identity does not exist" );
+ eos_assert( idents_table::exists( cert.identity ), "identity does not exist" );
/// the table exists in the scope of the identity
certs_table certs( cert.identity );
@@ -318,7 +331,7 @@ namespace identity {
row.trusted = is_trusted( cert.certifier );
row.certifier = cert.certifier;
row.confidence = value.confidence;
- assert(value.type.get_size() <= 32, "certrow::type shouldn't be longer than 32 bytes");
+ eos_assert(value.type.get_size() <= 32, "certrow::type should be not longer than 32 bytes");
row.type = value.type;
row.data = value.data;
@@ -328,19 +341,23 @@ namespace identity {
//special handling for owner
if (value.property == N(owner)) {
- assert(sizeof(account_name) == value.data.size(), "data size doesn't match account_name size");
+ eos_assert(sizeof(account_name) == value.data.size(), "data size doesn't match account_name size");
account_name acnt = *reinterpret_cast(value.data.data());
- accounts_table::set( acnt, cert.identity );
+ if (cert.certifier == acnt) { //only self-certitication affects accounts_table
+ accounts_table::set( cert.identity, acnt );
+ }
}
} else {
- //remove both tursted and untrusted because we cannot now if it was trusted back at creation time
+ //remove both tursted and untrusted because we cannot know if it was trusted back at creation time
certs.remove(value.property, 0, cert.certifier);
certs.remove(value.property, 1, cert.certifier);
//special handling for owner
if (value.property == N(owner)) {
- assert(sizeof(account_name) == value.data.size(), "data size doesn't match account_name size");
+ eos_assert(sizeof(account_name) == value.data.size(), "data size doesn't match account_name size");
account_name acnt = *reinterpret_cast(value.data.data());
- accounts_table::remove( acnt, cert.identity );
+ if (cert.certifier == acnt) { //only self-certitication affects accounts_table
+ accounts_table::remove( acnt );
+ }
}
}
}
diff --git a/contracts/identity/test/CMakeLists.txt b/contracts/identity/test/CMakeLists.txt
index 59eacaf0e53aa3bb4fe7cb0a10981bbb9dae4b3a..c0b42bd88413db7a21fe37240fe6b30f900f6e12 100644
--- a/contracts/identity/test/CMakeLists.txt
+++ b/contracts/identity/test/CMakeLists.txt
@@ -1,3 +1,7 @@
set(ABI_FILES "identity_test.abi")
configure_file("${ABI_FILES}" "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY)
-add_wast_target(identity_test "${CMAKE_SOURCE_DIR}/contracts" ${CMAKE_CURRENT_BINARY_DIR})
+add_wast_executable(TARGET identity_test
+ INCLUDE_FOLDERS "${STANDARD_INCLUDE_FOLDERS}"
+ LIBRARIES eosiolib
+ DESTINATION_FOLDER ${CMAKE_CURRENT_BINARY_DIR}
+)
diff --git a/contracts/infinite/CMakeLists.txt b/contracts/infinite/CMakeLists.txt
index 3285a93d1de2e51fd9956156449c23297eabdd8b..9960327f5246b788f0cc15f87efb0a486b2b9f28 100644
--- a/contracts/infinite/CMakeLists.txt
+++ b/contracts/infinite/CMakeLists.txt
@@ -1 +1,5 @@
-add_wast_target(infinite "${CMAKE_SOURCE_DIR}/contracts" ${CMAKE_CURRENT_BINARY_DIR})
+add_wast_executable(TARGET infinite
+ INCLUDE_FOLDERS "${STANDARD_INCLUDE_FOLDERS}"
+ LIBRARIES eosiolib
+ DESTINATION_FOLDER ${CMAKE_CURRENT_BINARY_DIR}
+)
diff --git a/contracts/infinite/infinite.cpp b/contracts/infinite/infinite.cpp
index 9da5585c521abd0a03750103c8567107de795161..0902e824731ed48ceea4e67260799b6d44284733 100644
--- a/contracts/infinite/infinite.cpp
+++ b/contracts/infinite/infinite.cpp
@@ -2,50 +2,15 @@
* @file
* @copyright defined in eos/LICENSE.txt
*/
-#include /// defines transfer struct (abi)
-
-namespace infinite {
- using namespace eosio;
-
- /// When storing accounts, check for empty balance and remove account
- void store_account( account_name account_to_store, const account& a ) {
- if( a.is_empty() ) {
- /// value, scope
- accounts::remove( a, account_to_store );
- } else {
- /// value, scope
- accounts::store( a, account_to_store );
- }
- }
-
- void apply_currency_transfer( const infinite::transfer& transfer ) {
- require_recipient( transfer.to, transfer.from );
- require_auth( transfer.from );
-
- auto from = get_account( transfer.from );
- auto to = get_account( transfer.to );
-
- while (from.balance > infinite::currency_tokens())
- {
- from.balance -= transfer.quantity; /// token subtraction has underflow assertion
- to.balance += transfer.quantity; /// token addition has overflow assertion
- }
-
- store_account( transfer.from, from );
- store_account( transfer.to, to );
- }
-
-} // namespace infinite
-
-using namespace infinite;
+#include /// defines transfer struct (abi)
extern "C" {
- /// The apply method implements the dispatch of events to this contract
- void apply( uint64_t code, uint64_t action ) {
- if( code == N(currency) ) {
- if( action == N(transfer) )
- infinite::apply_currency_transfer( current_action< infinite::transfer >() );
+ /// The apply method just prints forever
+ void apply( uint64_t, uint64_t ) {
+ int idx = 0;
+ while(true) {
+ eosio::print(idx++);
}
}
}
diff --git a/contracts/infinite/infinite.hpp b/contracts/infinite/infinite.hpp
deleted file mode 100644
index 2a85fefb4063a088e9fe931cce172d600cafc918..0000000000000000000000000000000000000000
--- a/contracts/infinite/infinite.hpp
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- * @file
- * @copyright defined in eos/LICENSE.txt
- */
-#include
-#include
-#include
-
-namespace infinite {
-
- typedef eosio::token currency_tokens;
-
- /**
- * transfer requires that the sender and receiver be the first two
- * accounts notified and that the sender has provided authorization.
- */
- struct transfer {
- account_name from;
- account_name to;
- currency_tokens quantity;
- };
-
- /**
- * @brief row in account table stored within each scope
- */
- struct account {
- account( currency_tokens b = currency_tokens() ):balance(b){}
-
- /**
- * The key is constant because there is only one record per scope/currency/accounts
- */
- const uint64_t key = N(account);
- currency_tokens balance;
-
- bool is_empty()const { return balance.quantity == 0; }
- };
- static_assert( sizeof(account) == sizeof(uint64_t)+sizeof(currency_tokens), "unexpected packing" );
-
- using accounts = eosio::table;
-
- /**
- * accounts information for owner is stored:
- *
- * owner/infinite/account/account -> account
- *
- * This API is made available for 3rd parties wanting read access to
- * the users balance. If the account doesn't exist a default constructed
- * account will be returned.
- */
- inline account get_account( account_name owner ) {
- account owned_account;
- /// scope, record
- accounts::get( owned_account, owner );
- return owned_account;
- }
-
-} /// namespace infinite
-
diff --git a/contracts/libc++/CMakeLists.txt b/contracts/libc++/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..72fd6a7853cc06eb54f7a02767d68ff830f2f436
--- /dev/null
+++ b/contracts/libc++/CMakeLists.txt
@@ -0,0 +1,15 @@
+SET(SRC_FILENAMES algorithm.cpp any.cpp bind.cpp condition_variable.cpp exception.cpp functional.cpp
+ future.cpp ios.cpp iostream.cpp locale.cpp memory.cpp mutex.cpp new.cpp optional.cpp
+ regex.cpp shared_mutex.cpp stdexcept.cpp string.cpp strstream.cpp system_error.cpp
+ thread.cpp typeinfo.cpp utility.cpp valarray.cpp variant.cpp vector.cpp)
+
+SET(SRC_FILES "")
+FOREACH(FN ${SRC_FILENAMES})
+ LIST(APPEND SRC_FILES "upstream/src/${FN}")
+ENDFOREACH(FN)
+
+add_wast_library(TARGET libc++
+ SOURCE_FILES "${SRC_FILES}"
+ INCLUDE_FOLDERS "${STANDARD_INCLUDE_FOLDERS}"
+ DESTINATION_FOLDER ${CMAKE_CURRENT_BINARY_DIR}
+)
diff --git a/contracts/libc++/upstream b/contracts/libc++/upstream
new file mode 160000
index 0000000000000000000000000000000000000000..35a26f82dae8b292290815ae6ede8f849ce7806f
--- /dev/null
+++ b/contracts/libc++/upstream
@@ -0,0 +1 @@
+Subproject commit 35a26f82dae8b292290815ae6ede8f849ce7806f
diff --git a/contracts/musl/CMakeLists.txt b/contracts/musl/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..3437ed1ce6d102358698aa58ec04f8ccd7fa9f24
--- /dev/null
+++ b/contracts/musl/CMakeLists.txt
@@ -0,0 +1,21 @@
+file(GLOB CRYPT_SOURCES "upstream/src/crypt/*.c")
+file(GLOB CTYPE_SOURCES "upstream/src/ctype/*.c")
+file(GLOB ENV_SOURCES "upstream/src/env/*.c")
+file(GLOB ERRNO_SOURCES "upstream/src/errno/*.c")
+file(GLOB EXIT_SOURCES "upstream/src/exit/*.c")
+file(GLOB LOCALE_SOURCES "upstream/src/locale/*.c")
+file(GLOB MBYTE_SOURCES "upstream/src/multibyte/*.c")
+file(GLOB SEARCH_SOURCES "upstream/src/search/*.c")
+file(GLOB STDIO_SOURCES "upstream/src/stdio/*.c")
+file(GLOB STDLIB_SOURCES "upstream/src/stdlib/*.c")
+file(GLOB STRING_SOURCES "upstream/src/string/*.c")
+file(GLOB TIME_SOURCES "upstream/src/time/*.c")
+file(GLOB THREAD_SOURCES "upstream/src/thread/*.c") #only for __lock __unlock
+file(GLOB INTERNAL_SOURCES upstream/src/internal/intscan.c upstream/src/internal/shgetc.c upstream/src/internal/libc.c)
+
+add_wast_library(TARGET libc
+ SOURCE_FILES ${CRYPT_SOURCES} ${CTYPE_SOURCES} ${ENV_SOURCES} ${ERRNO_SOURCES} ${EXIT_SOURCES} ${INTERNAL_SOURCES} ${LOCALE_SOURCES} ${MBYTE_SOURCES}
+ ${SEARCH_SOURCES} ${STDIO_SOURCES} ${STDLIB_SOURCES} ${STRING_SOURCES} ${TIME_SOURCES} ${THREAD_SOURCES}
+ INCLUDE_FOLDERS ${CMAKE_SOURCE_DIR}/contracts/musl/upstream/include ${CMAKE_SOURCE_DIR}/contracts/musl/upstream/src/internal ${CMAKE_SOURCE_DIR}/contracts/musl/upstream/arch/eos ${CMAKE_SOURCE_DIR}/contracts/
+ DESTINATION_FOLDER ${CMAKE_CURRENT_BINARY_DIR}
+)
diff --git a/contracts/musl/upstream b/contracts/musl/upstream
new file mode 160000
index 0000000000000000000000000000000000000000..29098b1f3044e7a9e2c1152028dba08885ea04f9
--- /dev/null
+++ b/contracts/musl/upstream
@@ -0,0 +1 @@
+Subproject commit 29098b1f3044e7a9e2c1152028dba08885ea04f9
diff --git a/contracts/noop/CMakeLists.txt b/contracts/noop/CMakeLists.txt
index 687e32fd39e3656dd3ad9dce31275251c65f5e14..694b4f1d0db888bb518b42caa104a9f97f2ab26f 100644
--- a/contracts/noop/CMakeLists.txt
+++ b/contracts/noop/CMakeLists.txt
@@ -1,3 +1,8 @@
file(GLOB ABI_FILES "*.abi")
configure_file("${ABI_FILES}" "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY)
-add_wast_target(noop "${CMAKE_SOURCE_DIR}/contracts" ${CMAKE_CURRENT_BINARY_DIR})
+add_wast_executable(TARGET noop
+ INCLUDE_FOLDERS "${STANDARD_INCLUDE_FOLDERS}"
+ LIBRARIES eosiolib
+ DESTINATION_FOLDER ${CMAKE_CURRENT_BINARY_DIR}
+)
+
diff --git a/contracts/proxy/CMakeLists.txt b/contracts/proxy/CMakeLists.txt
index 0761d788537d2542a6ca8c9463861d3b85c645c3..8a9e2f085c5a97f21f0cd9a74d238e917ee8fe82 100644
--- a/contracts/proxy/CMakeLists.txt
+++ b/contracts/proxy/CMakeLists.txt
@@ -1,3 +1,8 @@
file(GLOB ABI_FILES "*.abi")
configure_file("${ABI_FILES}" "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY)
-add_wast_target(proxy "${CMAKE_SOURCE_DIR}/contracts" ${CMAKE_CURRENT_BINARY_DIR})
+
+add_wast_executable(TARGET proxy
+ INCLUDE_FOLDERS "${STANDARD_INCLUDE_FOLDERS}"
+ LIBRARIES eosiolib
+ DESTINATION_FOLDER ${CMAKE_CURRENT_BINARY_DIR}
+)
diff --git a/contracts/proxy/proxy.cpp b/contracts/proxy/proxy.cpp
index ed5a7a734e744c87e8afb93fe34a665a62516c25..5f4b9167708fde76f496a107a5e844dbd097e3a7 100644
--- a/contracts/proxy/proxy.cpp
+++ b/contracts/proxy/proxy.cpp
@@ -5,20 +5,35 @@
#include
#include
#include
+#include
namespace proxy {
using namespace eosio;
+ namespace configs {
+ bool get(config &out, const account_name &self) {
+ auto read = load_i64(self, self, N(config), (char*)&out, sizeof(config));
+ if (read < 0) {
+ return false;
+ }
+ return true;
+ }
+
+ void store(const config &in, const account_name &self) {
+ store_i64(self, N(config), self, (const char *)&in, sizeof(config));
+ }
+ };
+
template
void apply_transfer(account_name code, const T& transfer) {
config code_config;
const auto self = current_receiver();
auto get_res = configs::get(code_config, self);
- assert(get_res, "Attempting to use unconfigured proxy");
+ eos_assert(get_res, "Attempting to use unconfigured proxy");
if (transfer.from == self) {
- assert(transfer.to == code_config.owner, "proxy may only pay its owner" );
+ eos_assert(transfer.to == code_config.owner, "proxy may only pay its owner" );
} else {
- assert(transfer.to == self, "proxy is not involved in this transfer");
+ eos_assert(transfer.to == self, "proxy is not involved in this transfer");
T new_transfer = T(transfer);
new_transfer.from = self;
new_transfer.to = code_config.owner;
@@ -47,7 +62,7 @@ namespace proxy {
eosio::print("starting onerror\n");
const auto self = current_receiver();
config code_config;
- assert(configs::get(code_config, self), "Attempting use of unconfigured proxy");
+ eos_assert(configs::get(code_config, self), "Attempting use of unconfigured proxy");
auto id = code_config.next_id++;
configs::store(code_config, self);
@@ -67,10 +82,12 @@ extern "C" {
if ( code == N(eosio)) {
if (action == N(onerror)) {
apply_onerror(deferred_transaction::from_current_action());
+ } if( action == N(transfer) ) {
+ apply_transfer(code, unpack_action::currency::transfer_memo>());
}
- } else if ( code == N(eosio.system) ) {
+ } else if ( code == N(currency) ) {
if( action == N(transfer) ) {
- apply_transfer(code, unpack_action::currency::transfer_memo>());
+ apply_transfer(code, unpack_action());
}
} else if (code == current_receiver() ) {
if ( action == N(setowner)) {
diff --git a/contracts/proxy/proxy.hpp b/contracts/proxy/proxy.hpp
index 5941e5a2e60c610c0ac94c2a9c19a16a6e9bb332..95a7e498ff6245835555c8bada0c31dadc4d6f08 100644
--- a/contracts/proxy/proxy.hpp
+++ b/contracts/proxy/proxy.hpp
@@ -3,7 +3,6 @@
* @copyright defined in eos/LICENSE.txt
*/
#include
-#include
namespace proxy {
@@ -22,6 +21,4 @@ namespace proxy {
uint32_t next_id = 0;
};
- using configs = eosio::table;
-
} /// namespace proxy
diff --git a/contracts/simpledb/CMakeLists.txt b/contracts/simpledb/CMakeLists.txt
index e1adb97ab5294a9dd10be4d2a24bcf5f57f5327e..acb36bda8eae6c60e3ad7a7cadb2031131d13941 100644
--- a/contracts/simpledb/CMakeLists.txt
+++ b/contracts/simpledb/CMakeLists.txt
@@ -1,3 +1,7 @@
file(GLOB ABI_FILES "*.abi")
-add_wast_target(simpledb "${CMAKE_SOURCE_DIR}/contracts" ${CMAKE_CURRENT_BINARY_DIR})
+add_wast_executable(TARGET simpledb
+ INCLUDE_FOLDERS "${STANDARD_INCLUDE_FOLDERS}"
+ LIBRARIES eosiolib
+ DESTINATION_FOLDER ${CMAKE_CURRENT_BINARY_DIR}
+)
configure_file("${ABI_FILES}" "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY)
diff --git a/contracts/simpledb/simpledb.cpp b/contracts/simpledb/simpledb.cpp
index 1bb89de1d61ec336575386f6c5423c06276b4ac6..81b6c0703db498e4c63a87e378e907801a398db0 100644
--- a/contracts/simpledb/simpledb.cpp
+++ b/contracts/simpledb/simpledb.cpp
@@ -54,7 +54,7 @@ extern "C" {
auto bytes = eosio::raw::pack(tmp);
store_i64i64i64( N(simpledb), N(record3), bytes.data, bytes.len);
} else {
- assert(0, "unknown message");
+ eos_assert(0, "unknown message");
}
}
}
diff --git a/contracts/simpledb/simpledb.gen.hpp b/contracts/simpledb/simpledb.gen.hpp
index ae3fb5bd57dad0fa1fe73cfb14f7e6f2df8693d0..eb6544cb6553b6a1c8b76a6f22e4ade8b9c516f6 100644
--- a/contracts/simpledb/simpledb.gen.hpp
+++ b/contracts/simpledb/simpledb.gen.hpp
@@ -83,7 +83,7 @@ namespace eosio {
Type current_message_ex() {
uint32_t size = action_size();
char* data = (char *)eosio::malloc(size);
- assert(data && read_action(data, size) == size, "error reading message");
+ eos_assert(data && read_action(data, size) == size, "error reading message");
Type value;
eosio::raw::unpack(data, size, value);
eosio::free(data);
diff --git a/contracts/social/CMakeLists.txt b/contracts/social/CMakeLists.txt
index 35b64147f3f902772567cd00ea65a647164e8c5a..72d5d9e059e10d0701cc03247835336d32b63db7 100644
--- a/contracts/social/CMakeLists.txt
+++ b/contracts/social/CMakeLists.txt
@@ -1 +1,5 @@
-add_wast_target(social "${CMAKE_SOURCE_DIR}/contracts" ${CMAKE_CURRENT_BINARY_DIR})
\ No newline at end of file
+add_wast_executable(TARGET social
+ INCLUDE_FOLDERS "${STANDARD_INCLUDE_FOLDERS}"
+ LIBRARIES eosiolib
+ DESTINATION_FOLDER ${CMAKE_CURRENT_BINARY_DIR}
+)
diff --git a/contracts/social/social.cpp b/contracts/social/social.cpp
index 194938445396d2feed501dd659ea040377f672b9..81baa67302601079a62f5fd95fb07d5ca2d582c9 100644
--- a/contracts/social/social.cpp
+++ b/contracts/social/social.cpp
@@ -62,7 +62,7 @@ void apply_social_post() {
const auto& post = current_action();
require_auth( post.author );
- assert( current_context() == post.author, "cannot call from any other context" );
+ eos_assert( current_context() == post.author, "cannot call from any other context" );
static post_record& existing;
if( !Db::get( post.postid, existing ) )
@@ -84,8 +84,8 @@ void apply_social_vote() {
if( context == vote.author ) {
static post_record post;
- assert( Db::get( vote.postid, post ) > 0, "unable to find post" );
- assert( now() - post.created < days(7), "cannot vote after 7 days" );
+ eos_assert( Db::get( vote.postid, post ) > 0, "unable to find post" );
+ eos_assert( now() - post.created < days(7), "cannot vote after 7 days" );
post.votes += vote.vote_power;
Db::store( vote.postid, post );
}
@@ -95,13 +95,13 @@ void apply_social_vote() {
auto abs_vote = abs(vote.vote_power);
vote_account.vote_power = min( vote_account.social_power,
vote_account.vote_power + (vote_account.social_power * (now()-last_vote)) / days(7));
- assert( abs_vote <= vote_account.vote_power, "insufficient vote power" );
+ eos_assert( abs_vote <= vote_account.vote_power, "insufficient vote power" );
post.votes += vote.vote_power;
vote_account.vote_power -= abs_vote;
vote_account.last_vote = now();
Db::store( "account", vote_account );
} else {
- assert( false, "invalid context for execution of this vote" );
+ eos_assert( false, "invalid context for execution of this vote" );
}
}
diff --git a/contracts/stltest/CMakeLists.txt b/contracts/stltest/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..81d615ebbf27dad3da61103336c75d878ca0e128
--- /dev/null
+++ b/contracts/stltest/CMakeLists.txt
@@ -0,0 +1,9 @@
+#file(GLOB ABI_FILES "*.abi")
+set(ABI_FILES "stltest.abi")
+add_wast_executable(TARGET stltest
+ INCLUDE_FOLDERS "${STANDARD_INCLUDE_FOLDERS}"
+ LIBRARIES libc++ libc eosiolib
+ DESTINATION_FOLDER ${CMAKE_CURRENT_BINARY_DIR}
+)
+
+configure_file("${ABI_FILES}" "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY)
diff --git a/contracts/stltest/stltest.abi b/contracts/stltest/stltest.abi
new file mode 100644
index 0000000000000000000000000000000000000000..969c44af8f62f0e0e14b5daa9b6e7ae6a9ff9bdf
--- /dev/null
+++ b/contracts/stltest/stltest.abi
@@ -0,0 +1,43 @@
+{
+ "types": [{
+ "new_type_name": "my_account_name",
+ "type": "name"
+ }
+ ],
+ "structs": [{
+ "name": "message",
+ "base": "",
+ "fields": [
+ {"name":"from", "type":"my_account_name"},
+ {"name":"to", "type":"my_account_name"},
+ {"name": "message", "type":"string" }
+ ]
+ },{
+ "name": "messages_count",
+ "base": "",
+ "fields": [
+ {"name": "user", "type": "my_account_name"},
+ {"name": "count", "type": "uint32"}
+ ]
+ }
+ ],
+ "actions": [{
+ "name": "message",
+ "type": "message"
+ }
+ ],
+ "tables": [{
+ "name": "msgsent",
+ "type": "messages_count",
+ "index_type": "i64",
+ "key_names" : ["user"],
+ "key_types" : ["my_account_name"]
+ },{
+ "name": "msgreceived",
+ "type": "messages_count",
+ "index_type": "i64",
+ "key_names" : ["user"],
+ "key_types" : ["my_account_name"]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/contracts/stltest/stltest.cpp b/contracts/stltest/stltest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9acb9435c433fb334c68cf4f877369a9ba0479a6
--- /dev/null
+++ b/contracts/stltest/stltest.cpp
@@ -0,0 +1,279 @@
+/**
+ * @file
+ * @copyright defined in eos/LICENSE.txt
+ */
+#include /// defines transfer struct (abi)
+
+// include entire libc
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+//include entire libstdc++
+#include
+#include
+#include
+#include
+#include
+//include
+#include
+#include
+//include
+#include
+//include
+#include
+#include
+#include
+#include
+#include
+#include
+//include
+#include
+//include
+//include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+//include
+#include
+#include
+#include
+#include
+#include
+#include
+//include
+#include
+//include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include